[GPU] 2.0 plugin api impl (#18920)
This commit is contained in:
1 parent
8e0d8dd36b
commit
47fe50ca35
90 files changed
+3413
-6313
No files matched your search
@@ -360,9 +360,9 @@ TEST_P(ov_remote_context_ocl, create_remote_tensor_nv12_from_ocl_image2D) {
|
||||
const int height = 480;
|
||||
const int width = 640;
|
||||
ov_shape_t shape_y = {0, nullptr};
|
||||
int64_t dims_y[4] = {1, 1, height, width};
|
||||
int64_t dims_y[4] = {1, height, width, 1};
|
||||
ov_shape_t shape_uv = {0, nullptr};
|
||||
int64_t dims_uv[4] = {1, 2, height / 2, width / 2};
|
||||
int64_t dims_uv[4] = {1, height / 2, width / 2, 2};
|
||||
|
||||
cl_int err;
|
||||
cl_image_format image_format;
|
||||
@@ -555,9 +555,9 @@ TEST_P(ov_remote_context_ocl, remote_tensor_nv12_inference) {
|
||||
EXPECT_NE(nullptr, context);
|
||||
|
||||
ov_shape_t shape_y = {0, nullptr};
|
||||
int64_t dims_y[4] = {1, 1, height, width};
|
||||
int64_t dims_y[4] = {1, height, width, 1};
|
||||
ov_shape_t shape_uv = {0, nullptr};
|
||||
int64_t dims_uv[4] = {1, 2, height / 2, width / 2};
|
||||
int64_t dims_uv[4] = {1, height / 2, width / 2, 2};
|
||||
|
||||
cl_int err;
|
||||
cl_image_format image_format;
|
||||
|
||||
@@ -151,12 +151,12 @@ protected:
|
||||
const std::function<void(ov::SoPtr<ov::ITensor>& tensor)>& allocate_callback);
|
||||
|
||||
std::unordered_map<std::shared_ptr<ov::descriptor::Tensor>, std::vector<ov::SoPtr<ov::ITensor>>> m_batched_tensors;
|
||||
ov::SoPtr<ov::ITensor>& get_tensor_ptr(const ov::Output<const ov::Node>& port) const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<const ov::ICompiledModel> m_compiled_model;
|
||||
// Mutable to return reference to ov::Tensor
|
||||
mutable std::unordered_map<std::shared_ptr<ov::descriptor::Tensor>, ov::SoPtr<ov::ITensor>> m_tensors;
|
||||
ov::SoPtr<ov::ITensor>& get_tensor_ptr(const ov::Output<const ov::Node>& port) const;
|
||||
|
||||
/**
|
||||
* @brief Finds input or output port
|
||||
|
||||
@@ -67,7 +67,7 @@ OPENVINO_RUNTIME_API ov::SoPtr<ov::ITensor> get_tensor_impl(const ov::Tensor& te
|
||||
|
||||
IE_SUPPRESS_DEPRECATED_START
|
||||
/** @cond INTERNAL */
|
||||
ov::SoPtr<ITensor> make_tensor(const std::shared_ptr<InferenceEngine::Blob>& tensor);
|
||||
ov::SoPtr<ITensor> make_tensor(const std::shared_ptr<InferenceEngine::Blob>& tensor, bool unwrap = false);
|
||||
const InferenceEngine::Blob* get_hardware_blob(const InferenceEngine::Blob* blob);
|
||||
InferenceEngine::Blob* get_hardware_blob(InferenceEngine::Blob* blob);
|
||||
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ie_ngraph_utils.hpp"
|
||||
#include "ie_remote_blob.hpp"
|
||||
#include "ie_remote_context.hpp"
|
||||
#include "openvino/runtime/iremote_context.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace legacy_convert {
|
||||
|
||||
INFERENCE_ENGINE_API_CPP(ov::SoPtr<ov::IRemoteContext>)
|
||||
convert_remote_context(const std::shared_ptr<InferenceEngine::RemoteContext>& context);
|
||||
INFERENCE_ENGINE_API_CPP(ie::Blob*) get_hardware_blob(ie::Blob* blob);
|
||||
|
||||
class INFERENCE_ENGINE_API_CLASS(TensorHolder) {
|
||||
public:
|
||||
TensorHolder(ov::SoPtr<ov::ITensor> tensor) : _tensor(tensor) {}
|
||||
|
||||
const ov::SoPtr<ov::ITensor>& get_tensor() const {
|
||||
return _tensor;
|
||||
}
|
||||
|
||||
private:
|
||||
ov::SoPtr<ov::ITensor> _tensor;
|
||||
};
|
||||
|
||||
} // namespace legacy_convert
|
||||
|
||||
/**
|
||||
* @brief Tensor what contains InferenceEngine::RemoteBlob inside
|
||||
* Blob owns the memory
|
||||
*/
|
||||
class INFERENCE_ENGINE_API_CLASS(RemoteBlobTensor) : public IRemoteTensor {
|
||||
mutable element::Type m_type;
|
||||
mutable Shape m_shape;
|
||||
mutable Strides m_strides;
|
||||
mutable ov::AnyMap m_properties;
|
||||
mutable std::string m_dev_name;
|
||||
|
||||
public:
|
||||
std::shared_ptr<ie::RemoteBlob> blob;
|
||||
|
||||
RemoteBlobTensor(const InferenceEngine::RemoteBlob::Ptr& blob) : blob{blob} {
|
||||
OPENVINO_ASSERT(blob);
|
||||
m_shape = blob->getTensorDesc().getBlockingDesc().getBlockDims();
|
||||
}
|
||||
|
||||
const element::Type& get_element_type() const override {
|
||||
m_type = InferenceEngine::details::convertPrecision(blob->getTensorDesc().getPrecision());
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void set_shape(ov::Shape shape) override {
|
||||
blob->setShape({shape.begin(), shape.end()});
|
||||
}
|
||||
|
||||
const Shape& get_shape() const override {
|
||||
m_shape = blob->getTensorDesc().getBlockingDesc().getBlockDims();
|
||||
return m_shape;
|
||||
}
|
||||
|
||||
const Strides& get_strides() const override {
|
||||
OPENVINO_ASSERT(get_element_type().bitwidth() >= 8,
|
||||
"Could not get strides for types with bitwidths less then 8 bit. Tensor type: ",
|
||||
get_element_type());
|
||||
const auto& element_strides = blob->getTensorDesc().getBlockingDesc().getStrides();
|
||||
const size_t elem_size = get_element_type().size();
|
||||
m_strides.clear();
|
||||
m_strides.resize(element_strides.size());
|
||||
std::transform(element_strides.begin(), element_strides.end(), m_strides.begin(), [&elem_size](size_t stride) {
|
||||
return stride * elem_size;
|
||||
});
|
||||
return m_strides;
|
||||
}
|
||||
|
||||
size_t get_size() const override {
|
||||
return blob->size();
|
||||
}
|
||||
|
||||
size_t get_byte_size() const override {
|
||||
return blob->byteSize();
|
||||
}
|
||||
|
||||
const AnyMap& get_properties() const override {
|
||||
m_properties = blob->getParams();
|
||||
return m_properties;
|
||||
}
|
||||
|
||||
const std::string& get_device_name() const override {
|
||||
m_dev_name = blob->getDeviceName();
|
||||
return m_dev_name;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create InferenceEngine::RemoteBlob from the Tensor
|
||||
*/
|
||||
class INFERENCE_ENGINE_API_CLASS(TensorRemoteBlob) : public ie::RemoteBlob, public ov::legacy_convert::TensorHolder {
|
||||
public:
|
||||
TensorRemoteBlob(const ov::SoPtr<ITensor>& tensor, ie::TensorDesc desc)
|
||||
: ie::RemoteBlob{desc},
|
||||
ov::legacy_convert::TensorHolder(tensor) {
|
||||
OPENVINO_ASSERT(this->get_tensor());
|
||||
}
|
||||
std::shared_ptr<ov::IRemoteTensor> cast_tensor() const {
|
||||
auto remote = std::dynamic_pointer_cast<ov::IRemoteTensor>(get_tensor()._ptr);
|
||||
OPENVINO_ASSERT(remote);
|
||||
return remote;
|
||||
}
|
||||
AnyMap getParams() const override {
|
||||
return cast_tensor()->get_properties();
|
||||
}
|
||||
std::string getDeviceName() const noexcept override {
|
||||
try {
|
||||
return cast_tensor()->get_device_name();
|
||||
} catch (...) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
std::shared_ptr<ie::RemoteContext> getContext() const noexcept override {
|
||||
return {};
|
||||
}
|
||||
|
||||
void allocate() noexcept override {}
|
||||
bool deallocate() noexcept override {
|
||||
return true;
|
||||
}
|
||||
ie::LockedMemory<void> buffer() noexcept override {
|
||||
return {nullptr, nullptr, 0};
|
||||
}
|
||||
ie::LockedMemory<const void> cbuffer() const noexcept override {
|
||||
return {nullptr, nullptr, 0};
|
||||
}
|
||||
ie::LockedMemory<void> rwmap() noexcept override {
|
||||
return {nullptr, nullptr, 0};
|
||||
}
|
||||
ie::LockedMemory<const void> rmap() const noexcept override {
|
||||
return {nullptr, nullptr, 0};
|
||||
}
|
||||
ie::LockedMemory<void> wmap() noexcept override {
|
||||
return {nullptr, nullptr, 0};
|
||||
}
|
||||
const std::shared_ptr<ie::IAllocator>& getAllocator() const noexcept override {
|
||||
return m_allocator;
|
||||
}
|
||||
void* getHandle() const noexcept override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
using TensorHolder::get_tensor;
|
||||
|
||||
private:
|
||||
std::shared_ptr<ie::IAllocator> m_allocator;
|
||||
};
|
||||
|
||||
} // namespace ov
|
||||
|
||||
namespace InferenceEngine {
|
||||
|
||||
class INFERENCE_ENGINE_API_CLASS(IRemoteContextWrapper) : public ov::IRemoteContext {
|
||||
private:
|
||||
std::shared_ptr<InferenceEngine::RemoteContext> m_context;
|
||||
mutable std::string m_name;
|
||||
mutable ov::AnyMap m_params;
|
||||
|
||||
public:
|
||||
IRemoteContextWrapper(const std::shared_ptr<InferenceEngine::RemoteContext>& context) : m_context(context) {}
|
||||
virtual ~IRemoteContextWrapper() = default;
|
||||
const std::shared_ptr<InferenceEngine::RemoteContext>& get_context();
|
||||
const std::string& get_device_name() const override;
|
||||
|
||||
const ov::AnyMap& get_property() const override;
|
||||
|
||||
ov::SoPtr<ov::IRemoteTensor> create_tensor(const ov::element::Type& type,
|
||||
const ov::Shape& shape,
|
||||
const ov::AnyMap& params = {}) override;
|
||||
ov::SoPtr<ov::ITensor> create_host_tensor(const ov::element::Type type, const ov::Shape& shape) override;
|
||||
};
|
||||
|
||||
} // namespace InferenceEngine
|
||||
@@ -139,7 +139,7 @@ public:
|
||||
* @param target_tile_id Desired tile id within given context for multi-tile system. Default value (-1) means
|
||||
* that root device should be used
|
||||
*/
|
||||
D3DContext(Core& core, ID3D11Device* device, int target_tile_id = -1) : ClContext(core, (cl_context) nullptr) {
|
||||
D3DContext(Core& core, ID3D11Device* device, int target_tile_id = -1) : ClContext() {
|
||||
// clang-format off
|
||||
AnyMap context_params = {
|
||||
{ov::intel_gpu::context_type.name(), ov::intel_gpu::ContextType::VA_SHARED},
|
||||
|
||||
@@ -177,6 +177,11 @@ protected:
|
||||
*/
|
||||
static constexpr const char* device_name = "GPU";
|
||||
|
||||
/**
|
||||
* @brief Default constructor which can be used in derived classes to avoid multiple create_context() calls
|
||||
*/
|
||||
ClContext() = default;
|
||||
|
||||
public:
|
||||
// Needed to make create_tensor overloads from base class visible for user
|
||||
using RemoteContext::create_tensor;
|
||||
|
||||
@@ -104,7 +104,7 @@ public:
|
||||
* @param target_tile_id Desired tile id within given context for multi-tile system. Default value (-1) means
|
||||
* that root device should be used
|
||||
*/
|
||||
VAContext(Core& core, VADisplay device, int target_tile_id = -1) : ClContext(core, (cl_context) nullptr) {
|
||||
VAContext(Core& core, VADisplay device, int target_tile_id = -1) : ClContext() {
|
||||
AnyMap context_params = {{ov::intel_gpu::context_type.name(), ov::intel_gpu::ContextType::VA_SHARED},
|
||||
{ov::intel_gpu::va_device.name(), static_cast<gpu_handle_param>(device)},
|
||||
{ov::intel_gpu::tile_id.name(), target_tile_id}};
|
||||
|
||||
@@ -215,7 +215,7 @@ public:
|
||||
}
|
||||
|
||||
void SetState(const InferenceEngine::Blob::Ptr& newState) override {
|
||||
m_state->set_state(ov::make_tensor(newState));
|
||||
m_state->set_state(ov::make_tensor(newState, true));
|
||||
}
|
||||
|
||||
InferenceEngine::Blob::CPtr GetState() const override {
|
||||
@@ -542,7 +542,7 @@ public:
|
||||
|
||||
void SetBlob(const std::string& name, const InferenceEngine::Blob::Ptr& data) override {
|
||||
try {
|
||||
m_request->set_tensor(find_port(name), ov::make_tensor(data));
|
||||
m_request->set_tensor(find_port(name), ov::make_tensor(data, true));
|
||||
} catch (const ov::Exception& ex) {
|
||||
const std::string what = ex.what();
|
||||
if (what.find("Failed to set tensor") != std::string::npos) {
|
||||
@@ -556,7 +556,7 @@ public:
|
||||
try {
|
||||
std::vector<ov::SoPtr<ov::ITensor>> tensors;
|
||||
for (const auto& blob : blobs) {
|
||||
tensors.emplace_back(ov::make_tensor(blob));
|
||||
tensors.emplace_back(ov::make_tensor(blob, true));
|
||||
}
|
||||
m_request->set_tensors(find_port(name), tensors);
|
||||
} catch (const ov::Exception& ex) {
|
||||
@@ -860,50 +860,40 @@ ov::SoPtr<::ov::IAsyncInferRequest> ov::legacy_convert::convert_infer_request(
|
||||
}
|
||||
|
||||
namespace InferenceEngine {
|
||||
const std::shared_ptr<InferenceEngine::RemoteContext>& IRemoteContextWrapper::get_context() {
|
||||
return m_context;
|
||||
}
|
||||
|
||||
class IRemoteContextWrapper : public ov::IRemoteContext {
|
||||
private:
|
||||
std::shared_ptr<InferenceEngine::RemoteContext> m_context;
|
||||
mutable std::string m_name;
|
||||
mutable ov::AnyMap m_params;
|
||||
const std::string& IRemoteContextWrapper::get_device_name() const {
|
||||
m_name = m_context->getDeviceName();
|
||||
return m_name;
|
||||
}
|
||||
|
||||
public:
|
||||
IRemoteContextWrapper(const std::shared_ptr<InferenceEngine::RemoteContext>& context) : m_context(context) {}
|
||||
virtual ~IRemoteContextWrapper() = default;
|
||||
const std::shared_ptr<InferenceEngine::RemoteContext>& get_context() {
|
||||
return m_context;
|
||||
}
|
||||
const std::string& get_device_name() const override {
|
||||
m_name = m_context->getDeviceName();
|
||||
return m_name;
|
||||
}
|
||||
const ov::AnyMap& IRemoteContextWrapper::get_property() const {
|
||||
m_params = m_context->getParams();
|
||||
return m_params;
|
||||
}
|
||||
|
||||
const ov::AnyMap& get_property() const override {
|
||||
m_params = m_context->getParams();
|
||||
return m_params;
|
||||
}
|
||||
ov::SoPtr<ov::IRemoteTensor> IRemoteContextWrapper::create_tensor(const ov::element::Type& type,
|
||||
const ov::Shape& shape,
|
||||
const ov::AnyMap& params) {
|
||||
InferenceEngine::TensorDesc desc(InferenceEngine::details::convertPrecision(type),
|
||||
shape,
|
||||
InferenceEngine::TensorDesc::getLayoutByDims(shape));
|
||||
auto blob = m_context->CreateBlob(desc, params);
|
||||
blob->allocate();
|
||||
auto tensor = ov::make_tensor(blob);
|
||||
return {std::dynamic_pointer_cast<ov::IRemoteTensor>(tensor._ptr), tensor._so};
|
||||
}
|
||||
|
||||
ov::SoPtr<ov::IRemoteTensor> create_tensor(const ov::element::Type& type,
|
||||
const ov::Shape& shape,
|
||||
const ov::AnyMap& params = {}) override {
|
||||
InferenceEngine::TensorDesc desc(InferenceEngine::details::convertPrecision(type),
|
||||
shape,
|
||||
InferenceEngine::TensorDesc::getLayoutByDims(shape));
|
||||
auto blob = m_context->CreateBlob(desc, params);
|
||||
blob->allocate();
|
||||
auto tensor = ov::make_tensor(blob);
|
||||
return {std::dynamic_pointer_cast<ov::IRemoteTensor>(tensor._ptr), tensor._so};
|
||||
}
|
||||
|
||||
ov::SoPtr<ov::ITensor> create_host_tensor(const ov::element::Type type, const ov::Shape& shape) override {
|
||||
InferenceEngine::TensorDesc desc(InferenceEngine::details::convertPrecision(type),
|
||||
shape,
|
||||
InferenceEngine::TensorDesc::getLayoutByDims(shape));
|
||||
auto blob = m_context->CreateHostBlob(desc);
|
||||
blob->allocate();
|
||||
return ov::make_tensor(blob);
|
||||
}
|
||||
};
|
||||
ov::SoPtr<ov::ITensor> IRemoteContextWrapper::create_host_tensor(const ov::element::Type type, const ov::Shape& shape) {
|
||||
InferenceEngine::TensorDesc desc(InferenceEngine::details::convertPrecision(type),
|
||||
shape,
|
||||
InferenceEngine::TensorDesc::getLayoutByDims(shape));
|
||||
auto blob = m_context->CreateHostBlob(desc);
|
||||
blob->allocate();
|
||||
return ov::make_tensor(blob);
|
||||
}
|
||||
|
||||
} // namespace InferenceEngine
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "openvino/runtime/icompiled_model.hpp"
|
||||
#include "openvino/runtime/iplugin.hpp"
|
||||
#include "openvino/runtime/iremote_context.hpp"
|
||||
#include "remote_utils.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace legacy_convert {
|
||||
@@ -40,11 +41,9 @@ ov::SoPtr<::ov::IAsyncInferRequest> convert_infer_request(
|
||||
const std::string& plugin_name = "");
|
||||
|
||||
std::shared_ptr<InferenceEngine::RemoteContext> convert_remote_context(const ov::SoPtr<ov::IRemoteContext>& context);
|
||||
ov::SoPtr<ov::IRemoteContext> convert_remote_context(const std::shared_ptr<InferenceEngine::RemoteContext>& context);
|
||||
|
||||
std::vector<ov::Extension::Ptr> convert_extension(const std::vector<InferenceEngine::IExtensionPtr>& exts);
|
||||
std::vector<InferenceEngine::IExtensionPtr> convert_extension(const std::vector<ov::Extension::Ptr>& exts);
|
||||
|
||||
} // namespace legacy_convert
|
||||
} // namespace ov
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "ie_remote_blob.hpp"
|
||||
#include "openvino/runtime/iremote_tensor.hpp"
|
||||
#include "openvino/runtime/properties.hpp"
|
||||
#include "remote_utils.hpp"
|
||||
#ifdef PROXY_PLUGIN_ENABLED
|
||||
# include "openvino/proxy/plugin.hpp"
|
||||
#endif
|
||||
@@ -371,131 +372,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Tensor what contains InferenceEngine::RemoteBlob inside
|
||||
* Blob owns the memory
|
||||
*/
|
||||
class RemoteBlobTensor : public IRemoteTensor {
|
||||
mutable element::Type m_type;
|
||||
mutable Shape m_shape;
|
||||
mutable Strides m_strides;
|
||||
mutable ov::AnyMap m_properties;
|
||||
mutable std::string m_dev_name;
|
||||
|
||||
public:
|
||||
std::shared_ptr<ie::RemoteBlob> blob;
|
||||
|
||||
RemoteBlobTensor(const InferenceEngine::RemoteBlob::Ptr& blob) : blob{blob} {
|
||||
OPENVINO_ASSERT(blob);
|
||||
m_shape = blob->getTensorDesc().getBlockingDesc().getBlockDims();
|
||||
}
|
||||
|
||||
const element::Type& get_element_type() const override {
|
||||
m_type = InferenceEngine::details::convertPrecision(blob->getTensorDesc().getPrecision());
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void set_shape(ov::Shape shape) override {
|
||||
blob->setShape({shape.begin(), shape.end()});
|
||||
}
|
||||
|
||||
const Shape& get_shape() const override {
|
||||
m_shape = blob->getTensorDesc().getBlockingDesc().getBlockDims();
|
||||
return m_shape;
|
||||
}
|
||||
|
||||
const Strides& get_strides() const override {
|
||||
OPENVINO_ASSERT(get_element_type().bitwidth() >= 8,
|
||||
"Could not get strides for types with bitwidths less then 8 bit. Tensor type: ",
|
||||
get_element_type());
|
||||
const auto& element_strides = blob->getTensorDesc().getBlockingDesc().getStrides();
|
||||
const size_t elem_size = get_element_type().size();
|
||||
m_strides.clear();
|
||||
m_strides.resize(element_strides.size());
|
||||
std::transform(element_strides.begin(), element_strides.end(), m_strides.begin(), [&elem_size](size_t stride) {
|
||||
return stride * elem_size;
|
||||
});
|
||||
return m_strides;
|
||||
}
|
||||
|
||||
size_t get_size() const override {
|
||||
return blob->size();
|
||||
}
|
||||
|
||||
size_t get_byte_size() const override {
|
||||
return blob->byteSize();
|
||||
}
|
||||
|
||||
const AnyMap& get_properties() const override {
|
||||
m_properties = blob->getParams();
|
||||
return m_properties;
|
||||
}
|
||||
|
||||
const std::string& get_device_name() const override {
|
||||
m_dev_name = blob->getDeviceName();
|
||||
return m_dev_name;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create InferenceEngine::RemoteBlob from the Tensor
|
||||
*/
|
||||
class TensorRemoteBlob : public ie::RemoteBlob {
|
||||
public:
|
||||
TensorRemoteBlob(const ov::SoPtr<ITensor>& tensor, ie::TensorDesc desc) : ie::RemoteBlob{desc}, tensor{tensor} {
|
||||
OPENVINO_ASSERT(this->tensor);
|
||||
}
|
||||
std::shared_ptr<ov::IRemoteTensor> cast_tensor() const {
|
||||
auto remote = std::dynamic_pointer_cast<ov::IRemoteTensor>(tensor._ptr);
|
||||
OPENVINO_ASSERT(remote);
|
||||
return remote;
|
||||
}
|
||||
AnyMap getParams() const override {
|
||||
return cast_tensor()->get_properties();
|
||||
}
|
||||
std::string getDeviceName() const noexcept override {
|
||||
try {
|
||||
return cast_tensor()->get_device_name();
|
||||
} catch (...) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
std::shared_ptr<ie::RemoteContext> getContext() const noexcept override {
|
||||
return {};
|
||||
}
|
||||
|
||||
void allocate() noexcept override {}
|
||||
bool deallocate() noexcept override {
|
||||
return true;
|
||||
}
|
||||
ie::LockedMemory<void> buffer() noexcept override {
|
||||
return {nullptr, nullptr, 0};
|
||||
}
|
||||
ie::LockedMemory<const void> cbuffer() const noexcept override {
|
||||
return {nullptr, nullptr, 0};
|
||||
}
|
||||
ie::LockedMemory<void> rwmap() noexcept override {
|
||||
return {nullptr, nullptr, 0};
|
||||
}
|
||||
ie::LockedMemory<const void> rmap() const noexcept override {
|
||||
return {nullptr, nullptr, 0};
|
||||
}
|
||||
ie::LockedMemory<void> wmap() noexcept override {
|
||||
return {nullptr, nullptr, 0};
|
||||
}
|
||||
const std::shared_ptr<ie::IAllocator>& getAllocator() const noexcept override {
|
||||
return m_allocator;
|
||||
}
|
||||
void* getHandle() const noexcept override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ov::SoPtr<ITensor> tensor;
|
||||
|
||||
private:
|
||||
std::shared_ptr<ie::IAllocator> m_allocator;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create InferenceEngine::TBlob<T> from the tensor
|
||||
*
|
||||
@@ -530,15 +406,17 @@ public:
|
||||
ov::SoPtr<ITensor> tensor;
|
||||
};
|
||||
|
||||
ov::SoPtr<ITensor> make_tensor(const std::shared_ptr<ie::Blob>& blob) {
|
||||
ov::SoPtr<ITensor> make_tensor(const std::shared_ptr<ie::Blob>& blob, bool unwrap) {
|
||||
#define ELSE_IF(type) \
|
||||
else if (auto tblob = dynamic_cast<const TensorMemoryBlob<type>*>(blob.get())) { \
|
||||
return tblob->tensor; \
|
||||
}
|
||||
if (blob == nullptr) {
|
||||
return {};
|
||||
} else if (unwrap && std::dynamic_pointer_cast<legacy_convert::TensorHolder>(blob) != nullptr) {
|
||||
return std::dynamic_pointer_cast<legacy_convert::TensorHolder>(blob)->get_tensor();
|
||||
} else if (auto remote_blob = std::dynamic_pointer_cast<TensorRemoteBlob>(blob)) {
|
||||
return remote_blob->tensor;
|
||||
return remote_blob->get_tensor();
|
||||
} else if (auto remote_blob = std::dynamic_pointer_cast<InferenceEngine::RemoteBlob>(blob)) {
|
||||
return {std::make_shared<RemoteBlobTensor>(remote_blob), nullptr};
|
||||
}
|
||||
@@ -564,7 +442,7 @@ ov::SoPtr<ITensor> make_tensor(const std::shared_ptr<ie::Blob>& blob) {
|
||||
ie::Blob* get_hardware_blob(ie::Blob* blob) {
|
||||
#ifdef PROXY_PLUGIN_ENABLED
|
||||
if (auto remote_blob = dynamic_cast<TensorRemoteBlob*>(blob)) {
|
||||
const auto& tensor = ov::proxy::get_hardware_tensor(remote_blob->tensor);
|
||||
const auto& tensor = ov::proxy::get_hardware_tensor(remote_blob->get_tensor());
|
||||
if (auto blob_tensor = std::dynamic_pointer_cast<BlobTensor>(tensor._ptr)) {
|
||||
return blob_tensor->blob.get();
|
||||
} else if (auto blob_tensor = std::dynamic_pointer_cast<RemoteBlobTensor>(tensor._ptr)) {
|
||||
@@ -579,7 +457,7 @@ ie::Blob* get_hardware_blob(ie::Blob* blob) {
|
||||
const ie::Blob* get_hardware_blob(const ie::Blob* blob) {
|
||||
#ifdef PROXY_PLUGIN_ENABLED
|
||||
if (auto remote_blob = dynamic_cast<const TensorRemoteBlob*>(blob)) {
|
||||
const auto& tensor = ov::proxy::get_hardware_tensor(remote_blob->tensor);
|
||||
const auto& tensor = ov::proxy::get_hardware_tensor(remote_blob->get_tensor());
|
||||
if (auto blob_tensor = std::dynamic_pointer_cast<BlobTensor>(tensor._ptr)) {
|
||||
return blob_tensor->blob.get();
|
||||
} else if (auto blob_tensor = std::dynamic_pointer_cast<RemoteBlobTensor>(tensor._ptr)) {
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
<a name="fig1"></a>
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
classDiagram
|
||||
direction LR
|
||||
pooling --<| primitive_base
|
||||
convolution --<| primitive_base
|
||||
convolution --<| primitive_base
|
||||
class primitive_base{<<PType>>}
|
||||
primitive_base --<| primitive
|
||||
primitive --o program_node
|
||||
@@ -78,7 +78,7 @@ A more detailed description of each component is described in the sections below
|
||||
|
||||
## primitive
|
||||
```cpp
|
||||
struct primitive {
|
||||
struct primitive {
|
||||
...
|
||||
const primitive_id id;
|
||||
const primitive_type* type;
|
||||
@@ -96,7 +96,7 @@ An example creation of a `arg_max_min` primitive:
|
||||
cldnn::arg_max_min top_k_prim = cldnn::arg_max_min("top_k", { "input" }, arg_max_min::max, top_k, arg_max_min::y, arg_max_min::sort_by_values, false, "", padding(), data_types::f32);
|
||||
```
|
||||
|
||||
In GPU plugin, the *primitives* are converted from ngraph [operations](https://github.com/openvinotoolkit/openvino/tree/master/src/plugins/intel_gpu/src/plugin/ops).
|
||||
In GPU plugin, the *primitives* are converted from OpenVINO [operations](https://github.com/openvinotoolkit/openvino/tree/master/src/plugins/intel_gpu/src/plugin/ops).
|
||||
|
||||
## topology
|
||||
```cpp
|
||||
@@ -200,7 +200,7 @@ class primitive_inst {
|
||||
std::vector<memory::cptr> _intermediates_memory;
|
||||
|
||||
event::ptr execute(const std::vector<event::ptr>& events);
|
||||
memory::ptr allocate_output();
|
||||
memory::ptr allocate_output();
|
||||
...
|
||||
};
|
||||
```
|
||||
|
||||
@@ -39,7 +39,7 @@ Behavior when both versions are specified is not defined.
|
||||
|
||||
Some options also allow multiple prefixes: `OV` and `OV_GPU`. `OV` prefix is intended to be used for options common for all OpenVINO components. When an option is set twice with different prefixes, then `OV_GPU` has higher priority.
|
||||
|
||||
### List of parameters
|
||||
### List of parameters
|
||||
|
||||
This is a part of the full list. To get all parameters, see OV_GPU_Help result.
|
||||
|
||||
@@ -66,12 +66,12 @@ This is a part of the full list. To get all parameters, see OV_GPU_Help result.
|
||||
|
||||
The execution graph (also known as a runtime graph) is a device-specific graph after all transformations applied by the plugin. It is a very useful
|
||||
feature for performance analysis and it allows finding a source of performance regressions quickly. The execution graph can be retrieved from the plugin
|
||||
using `GetExecGraphInfo()` method of `InferenceEngine::ExecutableNetwork` and then serialized as usual IR:
|
||||
using `get_runtime_model()` method of `ov::CompiledModel` and then serialized as usual IR:
|
||||
```cpp
|
||||
ExecutableNetwork exeNetwork;
|
||||
ov::CompiledModel compiled_model;
|
||||
// Load some model into the plugin
|
||||
CNNNetwork execGraphInfo = exeNetwork.GetExecGraphInfo();
|
||||
execGraphInfo.serialize("/path/to/serialized/exec/graph.xml");
|
||||
std::shared_ptr<ov::Model> runtime_model = compiled_model.get_runtime_model();
|
||||
ov::serialize(runtime_model, "/path/to/serialized/exec/graph.xml");
|
||||
```
|
||||
|
||||
The capability to retrieve the execution graph and store it on the disk is integrated into `benchmark_app`. The execution graph can be simply dumped
|
||||
@@ -116,14 +116,14 @@ Most of the data here is very handy for performance analysis. For example, for e
|
||||
|
||||
This graph can be visualized using Netron tool and all these properties can be analyzed there.
|
||||
|
||||
> **NOTE**: execution time collection for each primitive requires `CONFIG_KEY(PERF_COUNT)` to be enabled (`benchmark_app` does it automatically). Therefore, the overall model execution time is usually much worse in such use cases.
|
||||
> **NOTE**: execution time collection for each primitive requires `ov::enable_profiling` to be enabled (`benchmark_app` does it automatically). Therefore, the overall model execution time is usually much worse in such use cases.
|
||||
|
||||
## Performance counters
|
||||
|
||||
This feature is a simplified version of the execution graph as it provides much less information, but it might be more suitable for quick analysis and some kind of
|
||||
processing with scripts.
|
||||
|
||||
Performance counters can be retrieved from each `InferenceEngine::InferRequest` object using `getPerformanceCounts()` method. This feature is also integrated
|
||||
Performance counters can be retrieved from each `ov::InferRequest` object using `get_profiling_info()` method. This feature is also integrated
|
||||
into `benchmark_app` and the counters can be printed to count using `-pc` parameter.
|
||||
|
||||
The format looks as follows:
|
||||
@@ -149,14 +149,6 @@ So it allows you to quickly check the execution time of some operation on the de
|
||||
|
||||
* You can dump graphs with `OV_GPU_DumpGraphs` of debug config. For the usage of debug config, see the [link](#debug-config).
|
||||
|
||||
* Alternatively, you can also enable the dumps from the application source code:
|
||||
clDNN plugin has the special internal config option - `graph_dumps_dir`, which can be set from the user app via plugin config:
|
||||
```cpp
|
||||
Core ie;
|
||||
std::map<std::string, std::string> device_config;
|
||||
device_config[CLDNN_CONFIG_KEY(GRAPH_DUMPS_DIR)] = "/some/existing/path/";
|
||||
ie.SetConfig(device_config, "GPU");
|
||||
```
|
||||
|
||||
For each stage, it dumps:
|
||||
```
|
||||
@@ -175,14 +167,6 @@ Since *Intel_GPU* source tree contains only *templates* of the OpenCL™ kernels
|
||||
|
||||
* You can use `OV_GPU_DumpSources` of debug config. For the usage of debug config, see [link](#debug-config).
|
||||
|
||||
* You can also dump OpenCL source code by changing OpenVINO source code:
|
||||
clDNN plugin has the special internal config option - `sources_dumps_dir`, which can be set from the user app via plugin config:
|
||||
```cpp
|
||||
Core ie;
|
||||
std::map<std::string, std::string> device_config;
|
||||
device_config[CLDNN_CONFIG_KEY(SOURCES_DUMPS_DIR)] = "/some/existing/path/";
|
||||
ie.SetConfig(device_config, "GPU");
|
||||
```
|
||||
|
||||
When this key is enabled, the plugin dumps multiple files with the following names:
|
||||
```
|
||||
|
||||
@@ -3,69 +3,67 @@
|
||||
The simplified workflow in the GPU plugin is shown in the diagram below (click it for higher resolution):
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class `intel_gpu::Plugin` {Inference Engine plugin
|
||||
implementation for GPU}
|
||||
class `intel_gpu::CompiledModel` {Device specific network
|
||||
representation that can be executed}
|
||||
class `intel_gpu::InferRequestAsync` {
|
||||
Inference request for specific executable network.
|
||||
Wrapper for input and output memory}
|
||||
class `intel_gpu::TransformationPipeline` {Set of ngraph-based transformations
|
||||
configured by GPU plugin}
|
||||
`Core::compile_model()` --> `intel_gpu::CompiledModel`
|
||||
`CompiledModel::create_infer_request()` -->`intel_gpu::InferRequestAsync`
|
||||
`InferRequest::start_async()` --> `intel_gpu::network`
|
||||
`intel_gpu::Plugin` --|> `InferenceEngine::InferencePluginInternal`
|
||||
classDiagram
|
||||
|
||||
%% Public API classes
|
||||
class `ov::CompiledModel`
|
||||
class `ov::InferRequest`
|
||||
class `ov::Core`
|
||||
|
||||
%% Plugin API interface %%
|
||||
class `ov::IPlugin`
|
||||
class `ov::ICompiledModel`
|
||||
class `ov::IAsyncInferRequest`
|
||||
class `ov::ISyncInferRequest`
|
||||
|
||||
%% Plugin API Impl %%
|
||||
class `intel_gpu::Plugin` { OpenVINO plugin implementation for GPU }
|
||||
class `intel_gpu::CompiledModel`
|
||||
class `intel_gpu::AsyncInferRequest` { Asynchronous version of infer request }
|
||||
class `intel_gpu::SyncInferRequest` { Inference request for specific executable network. Wrapper for input and output memory }
|
||||
|
||||
`intel_gpu::Plugin` --|> `ov::IPlugin`
|
||||
`intel_gpu::CompiledModel` --|> `ov::ICompiledModel`
|
||||
`intel_gpu::SyncInferRequest` --|> `ov::ISyncInferRequest`
|
||||
`intel_gpu::AsyncInferRequest` --|> `ov::IAsyncInferRequest`
|
||||
`intel_gpu::Plugin` --> `intel_gpu::CompiledModel` : Create
|
||||
`intel_gpu::CompiledModel` --|> `InferenceEngine::ExecutableNetworkThreadSafeDefault`
|
||||
`intel_gpu::CompiledModel` --> `intel_gpu::InferRequestAsync` : Create
|
||||
`intel_gpu::SyncInferRequest` "1" --* "1" `intel_gpu::AsyncInferRequest`
|
||||
|
||||
%% Plugin implementation details %%
|
||||
class `intel_gpu::TransformationPipeline` {Set of ngraph-based transformations configured by GPU plugin }
|
||||
class `intel_gpu::Graph` { Per stream copy of compiled graph with independent memory }
|
||||
class `intel_gpu::ProgramBuilder` { Object for operations semantic translation and graph compilation }
|
||||
|
||||
`ov::Core` --> `intel_gpu::CompiledModel` : compile_model()
|
||||
`ov::CompiledModel` -->`intel_gpu::AsyncInferRequest` : create_infer_request()
|
||||
`ov::InferRequest` --> `intel_gpu::network` : start_async()
|
||||
`intel_gpu::CompiledModel` --> `intel_gpu::AsyncInferRequest` : Create
|
||||
`intel_gpu::TransformationPipeline` --> `ov::Model`
|
||||
`intel_gpu::TransformationPipeline` --> `intel_gpu::CompiledModel`
|
||||
`InferenceEngine::InferRequestInternal`
|
||||
class `intel_gpu::Graph` {Per stream copy of
|
||||
compiled graph with
|
||||
independent memory}
|
||||
`intel_gpu::Graph` "1..N" --* `intel_gpu::CompiledModel`
|
||||
class `intel_gpu::ProgramBuilder` {Object for operations
|
||||
semantic translation and
|
||||
graph compilation}
|
||||
`intel_gpu::CompiledModel` --> `intel_gpu::ProgramBuilder` : Create
|
||||
`intel_gpu::ProgramBuilder` "1" --o "N" `intel_gpu::Graph`
|
||||
|
||||
class `intel_gpu::convolution` {convolution operation descriptor}
|
||||
class `intel_gpu::data` {Primitive representing
|
||||
constant data in a topology}
|
||||
class `intel_gpu::data` {Primitive representing constant data in a topology }
|
||||
class `intel_gpu::input_layout` {Represents dynamic input data}
|
||||
class `intel_gpu::primitive_base` {<<Interface>>}
|
||||
`intel_gpu::convolution` ..<| `intel_gpu::primitive_base`
|
||||
`intel_gpu::data` ..<| `intel_gpu::primitive_base`
|
||||
`intel_gpu::input_layout` ..<| `intel_gpu::primitive_base`
|
||||
`Any other primitive` ..<| `intel_gpu::primitive_base`
|
||||
class `intel_gpu::topology` {
|
||||
Set of primitives. Each primitive
|
||||
knows operation parameters,
|
||||
it's inputs and outputs}
|
||||
class `intel_gpu::program` {
|
||||
Class that contains compiled topology.
|
||||
All kernels are selected,
|
||||
memory dependencies are resolved,
|
||||
the only missing thing - memory for intermediate buffers}
|
||||
class `intel_gpu::topology` { Set of primitives. Each primitive knows operation parameters, it's inputs and outputs }
|
||||
class `intel_gpu::program` { Class that contains compiled topology. All kernels are selected, memory dependencies are resolved, the only missing thing - memory for intermediate buffers }
|
||||
`intel_gpu::primitive_base` "0..N" --o `intel_gpu::topology`
|
||||
`intel_gpu::program` --> `intel_gpu::topology`
|
||||
`intel_gpu::ProgramBuilder` --> `intel_gpu::topology` : Create
|
||||
`intel_gpu::ProgramBuilder` --> `intel_gpu::program` : Create
|
||||
class `intel_gpu::program_node` {Base class for representation of a single graph node}
|
||||
class `intel_gpu::primitive_impl` {
|
||||
<<interface>>
|
||||
Base class for representation of a single graph node}
|
||||
class `intel_gpu::typed_primitive_onednn_impl` {Implementations that use oneDNN library}
|
||||
class `oneDNN library` {statically linked into GPU plugin}
|
||||
class `intel_gpu::typed_primitive_ocl_impl` {OCL implementations that use
|
||||
kernels from kernel_selector}
|
||||
class `intel_gpu::kernel_selector` {
|
||||
module that stores OCL kernels
|
||||
for primitives and has embed some
|
||||
rules for optimal kernel selection}
|
||||
class `intel_gpu::program_node` { Base class for representation of a single graph node }
|
||||
class `intel_gpu::primitive_impl` { <<interface>> Base class for representation of a single graph node }
|
||||
class `intel_gpu::typed_primitive_onednn_impl` {Implementations that use oneDNN library }
|
||||
class `oneDNN library` { statically linked into GPU plugin }
|
||||
class `intel_gpu::typed_primitive_ocl_impl` { OCL implementations that use kernels from kernel_selector }
|
||||
class `intel_gpu::kernel_selector` { module that stores OCL kernels for primitives and has embed some rules for optimal kernel selection }
|
||||
`intel_gpu::program_node` --o `intel_gpu::program`
|
||||
`intel_gpu::primitive_impl` --o `intel_gpu::program_node`
|
||||
`intel_gpu::typed_primitive_onednn_impl` ..<| `intel_gpu::primitive_impl`
|
||||
@@ -73,26 +71,18 @@ rules for optimal kernel selection}
|
||||
`intel_gpu::typed_primitive_ocl_impl` ..> `intel_gpu::kernel_selector`
|
||||
`intel_gpu::typed_primitive_onednn_impl` --> `oneDNN bridge` : Use
|
||||
`intel_gpu::typed_primitive_onednn_impl` ..> `oneDNN library`
|
||||
class `intel_gpu::build_options` {Set of options for graph compilations}
|
||||
class `intel_gpu::pass_manager` {Helper to run graph transformations}
|
||||
class `intel_gpu::base_pass` {
|
||||
<<Interface>>
|
||||
Base class for graph transformations}
|
||||
class `intel_gpu::build_options` { Set of options for graph compilations }
|
||||
class `intel_gpu::pass_manager` { Helper to run graph transformations }
|
||||
class `intel_gpu::base_pass` { <<Interface>> Base class for graph transformations}
|
||||
`intel_gpu::program` --> `intel_gpu::build_options`
|
||||
`intel_gpu::program` --> `intel_gpu::pass_manager` : Use
|
||||
`intel_gpu::program` --> `intel_gpu::base_pass` : Use
|
||||
`intel_gpu::pass_manager` --> `intel_gpu::base_pass` : Run
|
||||
class `intel_gpu::prepare_primitive_fusing` {
|
||||
Pass that fuses multiple operations into single node}
|
||||
class `intel_gpu::prepare_quantization` {
|
||||
Pass that prepares models for low precision execution}
|
||||
class `intel_gpu::reorder_inputs` {
|
||||
Pass that is responsible for layout/impl selection}
|
||||
class `intel_gpu::compile_graph` {
|
||||
Pass that selects and creates
|
||||
best implementation for each primitive}
|
||||
class `intel_gpu::remove_redundant_reorders` {
|
||||
Pass that optimizes reorders in the graph}
|
||||
class `intel_gpu::prepare_primitive_fusing` { Pass that fuses multiple operations into single node }
|
||||
class `intel_gpu::prepare_quantization` { Pass that prepares models for low precision execution }
|
||||
class `intel_gpu::reorder_inputs` { Pass that is responsible for layout/impl selection }
|
||||
class `intel_gpu::compile_graph` { Pass that selects and creates best implementation for each primitive }
|
||||
class `intel_gpu::remove_redundant_reorders` { Pass that optimizes reorders in the graph }
|
||||
`intel_gpu::prepare_primitive_fusing`--|> `intel_gpu::base_pass`
|
||||
`intel_gpu::prepare_quantization`--|> `intel_gpu::base_pass`
|
||||
`intel_gpu::reorder_inputs`--|> `intel_gpu::base_pass`
|
||||
@@ -100,31 +90,23 @@ Pass that optimizes reorders in the graph}
|
||||
`intel_gpu::layout_optimizer`--|> `intel_gpu::base_pass`
|
||||
`intel_gpu::remove_redundant_reorders`--|> `intel_gpu::base_pass`
|
||||
`intel_gpu::reorder_inputs`--> `intel_gpu::layout_optimizer` : Use
|
||||
class `intel_gpu::network` {
|
||||
A program with allocated memory.
|
||||
Can be executed on the device}
|
||||
`intel_gpu::InferRequestAsync` --> `intel_gpu::network` : Set input/output memory and run execution
|
||||
`intel_gpu::network` --> `intel_gpu::InferRequestAsync` : Return inference result
|
||||
class `intel_gpu::tensor` {Size of memory buffer}
|
||||
class `intel_gpu::format` {Order of elements in memory}
|
||||
class `intel_gpu::data_type` {elements precision}
|
||||
class `intel_gpu::memory_pool` {
|
||||
Object that tracks memory allocations
|
||||
and tries to reuse memory buffers}
|
||||
class `intel_gpu::layout` {Memory descriptor}
|
||||
class `intel_gpu::memory` {GPU memory object}
|
||||
class `intel_gpu::stream` {
|
||||
Abstraction for queue.
|
||||
Knows how to submit kernels and
|
||||
provide some synchronization capabilities}
|
||||
class `intel_gpu::event` {Synchronization primitive}
|
||||
class `intel_gpu::kernel` {Holds kernel handle}
|
||||
class `intel_gpu::engine` {Engine for specific device,
|
||||
responsible for memory allocations}
|
||||
class `intel_gpu::device` {Holds context/device handles for selected backend}
|
||||
class `intel_gpu::device_info` {Storage for device capabilities and info}
|
||||
class `intel_gpu::engine_configuration` {Options for engine}
|
||||
class `intel_gpu::device_query` {Detects available devices for given backend}
|
||||
class `intel_gpu::network` { A program with allocated memory.Can be executed on the device }
|
||||
`intel_gpu::AsyncInferRequest` --> `intel_gpu::network` : Set input/output memory and run execution
|
||||
`intel_gpu::network` --> `intel_gpu::AsyncInferRequest` : Return inference result
|
||||
class `intel_gpu::tensor` { Size of memory buffer }
|
||||
class `intel_gpu::format` { Order of elements in memory }
|
||||
class `intel_gpu::data_type` { elements precision }
|
||||
class `intel_gpu::memory_pool` { Object that tracks memory allocations and tries to reuse memory buffers }
|
||||
class `intel_gpu::layout` { Memory descriptor }
|
||||
class `intel_gpu::memory` { GPU memory object }
|
||||
class `intel_gpu::stream` { Abstraction for queue. Knows how to submit kernels and provide some synchronization }
|
||||
class `intel_gpu::event` { Synchronization primitive }
|
||||
class `intel_gpu::kernel` { Holds kernel handle }
|
||||
class `intel_gpu::engine` { Engine for specific device, responsible for memory allocations }
|
||||
class `intel_gpu::device` { Holds context/device handles for selected backend }
|
||||
class `intel_gpu::device_info` { Storage for device capabilities and info }
|
||||
class `intel_gpu::engine_configuration` { Options for engine }
|
||||
class `intel_gpu::device_query` { Detects available devices for given backend }
|
||||
`intel_gpu::tensor` --o `intel_gpu::layout`
|
||||
`intel_gpu::format` --o `intel_gpu::layout`
|
||||
`intel_gpu::data_type` --o `intel_gpu::layout`
|
||||
@@ -142,8 +124,6 @@ class `intel_gpu::device_query` {Detects available devices for given backend}
|
||||
`intel_gpu::device` --o `intel_gpu::engine`
|
||||
`intel_gpu::device_info` --o `intel_gpu::device`
|
||||
`intel_gpu::device_query` --> `intel_gpu::device`
|
||||
`OCL Implementation of Runtime`..<| `Runtime module API & common`
|
||||
`SYCL/L0 Implementation of Runtime (POC)`..<| `Runtime module API & common`
|
||||
```
|
||||
|
||||
## See also
|
||||
@@ -152,4 +132,4 @@ class `intel_gpu::device_query` {Detects available devices for given backend}
|
||||
* [OpenVINO Core Components](../../../README.md)
|
||||
* [OpenVINO Plugins](../../README.md)
|
||||
* [OpenVINO GPU Plugin](../README.md)
|
||||
* [Developer documentation](../../../../docs/dev/index.md)
|
||||
* [Developer documentation](../../../../docs/dev/index.md)
|
||||
@@ -244,7 +244,7 @@ public:
|
||||
|
||||
using variables_state_info_map = std::map<std::string, cldnn::layout>;
|
||||
void set_variables_state_info(const std::string& variable_id, const cldnn::layout& layout);
|
||||
|
||||
const variables_state_info_map& get_variables_state_info() const;
|
||||
const ExecutionConfig& get_config() const { return _config; }
|
||||
|
||||
ShapePredictor& get_shape_predictor() { return *_shape_predictor; }
|
||||
|
||||
@@ -6,43 +6,11 @@
|
||||
|
||||
#define RUN_ALL_MODEL_CACHING_TESTS
|
||||
|
||||
#include <vector>
|
||||
#include <streambuf>
|
||||
#include <unordered_map>
|
||||
#include "openvino/core/deprecated.hpp"
|
||||
#include "ie/ie_common.h"
|
||||
|
||||
namespace cldnn {
|
||||
class serial_util {
|
||||
public:
|
||||
OPENVINO_SUPPRESS_DEPRECATED_START
|
||||
static InferenceEngine::Layout layout_from_string(const std::string& name) {
|
||||
static const std::unordered_map<std::string, InferenceEngine::Layout> layouts = {
|
||||
{ "ANY", InferenceEngine::Layout::ANY },
|
||||
{ "NCHW", InferenceEngine::Layout::NCHW },
|
||||
{ "NHWC", InferenceEngine::Layout::NHWC },
|
||||
{ "NCDHW", InferenceEngine::Layout::NCDHW },
|
||||
{ "NDHWC", InferenceEngine::Layout::NDHWC },
|
||||
{ "OIHW", InferenceEngine::Layout::OIHW },
|
||||
{ "GOIHW", InferenceEngine::Layout::GOIHW },
|
||||
{ "OIDHW", InferenceEngine::Layout::OIDHW },
|
||||
{ "GOIDHW", InferenceEngine::Layout::GOIDHW },
|
||||
{ "SCALAR", InferenceEngine::Layout::SCALAR },
|
||||
{ "C", InferenceEngine::Layout::C },
|
||||
{ "CHW", InferenceEngine::Layout::CHW },
|
||||
{ "HWC", InferenceEngine::Layout::HWC },
|
||||
{ "HW", InferenceEngine::Layout::HW },
|
||||
{ "NC", InferenceEngine::Layout::NC },
|
||||
{ "CN", InferenceEngine::Layout::CN },
|
||||
{ "BLOCKED", InferenceEngine::Layout::BLOCKED }
|
||||
};
|
||||
auto it = layouts.find(name);
|
||||
if (it != layouts.end()) {
|
||||
return it->second;
|
||||
}
|
||||
OPENVINO_THROW("Unknown layout with name '", name, "'");
|
||||
}
|
||||
OPENVINO_SUPPRESS_DEPRECATED_END
|
||||
};
|
||||
|
||||
class membuf : public std::streambuf {
|
||||
public:
|
||||
membuf() : _pos(0) { }
|
||||
|
||||
@@ -4,29 +4,29 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/runtime/iasync_infer_request.hpp"
|
||||
#include "intel_gpu/plugin/sync_infer_request.hpp"
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <cpp_interfaces/impl/ie_infer_async_request_thread_safe_default.hpp>
|
||||
#include "intel_gpu/plugin/infer_request.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
class AsyncInferRequest : public InferenceEngine::AsyncInferRequestThreadSafeDefault {
|
||||
class AsyncInferRequest : public ov::IAsyncInferRequest {
|
||||
public:
|
||||
using Parent = InferenceEngine::AsyncInferRequestThreadSafeDefault;
|
||||
AsyncInferRequest(const InferRequest::Ptr &inferRequest,
|
||||
const InferenceEngine::ITaskExecutor::Ptr& taskExecutor,
|
||||
const InferenceEngine::ITaskExecutor::Ptr& waitExecutor,
|
||||
const InferenceEngine::ITaskExecutor::Ptr& callbackExecutor);
|
||||
using Parent = ov::IAsyncInferRequest;
|
||||
AsyncInferRequest(const std::shared_ptr<SyncInferRequest>& infer_request,
|
||||
const std::shared_ptr<ov::threading::ITaskExecutor>& task_executor,
|
||||
const std::shared_ptr<ov::threading::ITaskExecutor>& wait_executor,
|
||||
const std::shared_ptr<ov::threading::ITaskExecutor>& callback_executor);
|
||||
|
||||
~AsyncInferRequest();
|
||||
~AsyncInferRequest() override;
|
||||
|
||||
void StartAsync_ThreadUnsafe() override;
|
||||
void start_async() override;
|
||||
|
||||
private:
|
||||
InferRequest::Ptr _inferRequest;
|
||||
InferenceEngine::ITaskExecutor::Ptr _waitExecutor;
|
||||
std::shared_ptr<SyncInferRequest> m_infer_request;
|
||||
std::shared_ptr<ov::threading::ITaskExecutor> m_wait_executor;
|
||||
};
|
||||
|
||||
} // namespace intel_gpu
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <cpp_interfaces/impl/ie_infer_async_request_thread_safe_default.hpp>
|
||||
#include "intel_gpu/plugin/infer_request_legacy.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
class AsyncInferRequestLegacy : public InferenceEngine::AsyncInferRequestThreadSafeDefault {
|
||||
public:
|
||||
using Parent = InferenceEngine::AsyncInferRequestThreadSafeDefault;
|
||||
AsyncInferRequestLegacy(const InferRequestLegacy::Ptr &inferRequest,
|
||||
const InferenceEngine::ITaskExecutor::Ptr& taskExecutor,
|
||||
const InferenceEngine::ITaskExecutor::Ptr& waitExecutor,
|
||||
const InferenceEngine::ITaskExecutor::Ptr& callbackExecutor);
|
||||
|
||||
~AsyncInferRequestLegacy();
|
||||
|
||||
void StartAsync_ThreadUnsafe() override;
|
||||
|
||||
private:
|
||||
InferRequestLegacy::Ptr _inferRequest;
|
||||
InferenceEngine::ITaskExecutor::Ptr _waitExecutor;
|
||||
};
|
||||
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
@@ -4,16 +4,26 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ie_layouts.h>
|
||||
#include <ostream>
|
||||
#include "intel_gpu/runtime/layout.hpp"
|
||||
#include "openvino/core/layout.hpp"
|
||||
#include "openvino/core/deprecated.hpp"
|
||||
|
||||
#include "ngraph/type/element_type.hpp"
|
||||
#include "openvino/core/type/element_type.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
enum class TensorType {
|
||||
BT_EMPTY,
|
||||
BT_BUF_INTERNAL,
|
||||
BT_BUF_SHARED,
|
||||
BT_USM_SHARED,
|
||||
BT_USM_HOST_INTERNAL,
|
||||
BT_USM_DEVICE_INTERNAL,
|
||||
BT_IMG_SHARED,
|
||||
BT_SURF_SHARED,
|
||||
BT_DX_BUF_SHARED,
|
||||
};
|
||||
|
||||
#define TensorValue(val) static_cast<cldnn::tensor::value_type>(val)
|
||||
|
||||
inline cldnn::tensor tensor_from_dims(const ov::Shape& dims, int def = 1) {
|
||||
@@ -29,121 +39,25 @@ inline cldnn::tensor tensor_from_dims(const ov::Shape& dims, int def = 1) {
|
||||
}
|
||||
}
|
||||
|
||||
OPENVINO_SUPPRESS_DEPRECATED_START
|
||||
inline cldnn::data_types DataTypeFromPrecision(InferenceEngine::Precision p) {
|
||||
switch (p) {
|
||||
case InferenceEngine::Precision::I16:
|
||||
case InferenceEngine::Precision::U16:
|
||||
case InferenceEngine::Precision::FP32:
|
||||
case InferenceEngine::Precision::FP64:
|
||||
return cldnn::data_types::f32;
|
||||
case InferenceEngine::Precision::FP16:
|
||||
return cldnn::data_types::f16;
|
||||
case InferenceEngine::Precision::U8:
|
||||
return cldnn::data_types::u8;
|
||||
case InferenceEngine::Precision::I8:
|
||||
return cldnn::data_types::i8;
|
||||
case InferenceEngine::Precision::I32:
|
||||
case InferenceEngine::Precision::U32:
|
||||
case InferenceEngine::Precision::U64:
|
||||
return cldnn::data_types::i32;
|
||||
case InferenceEngine::Precision::I64:
|
||||
return cldnn::data_types::i64;
|
||||
case InferenceEngine::Precision::BIN:
|
||||
return cldnn::data_types::bin;
|
||||
case InferenceEngine::Precision::BOOL:
|
||||
return cldnn::data_types::i8;
|
||||
default:
|
||||
IE_THROW(ParameterMismatch)
|
||||
<< "The plugin does not support " << p.name() << " precision";
|
||||
}
|
||||
inline cldnn::layout make_layout(const ov::element::Type type, const ov::Shape& shape) {
|
||||
return cldnn::layout{ov::PartialShape{shape},
|
||||
cldnn::element_type_to_data_type(type),
|
||||
cldnn::format::get_default_format(shape.size())};
|
||||
}
|
||||
|
||||
inline InferenceEngine::Precision PrecisionFromDataType(cldnn::data_types dt) {
|
||||
switch (dt) {
|
||||
case cldnn::data_types::bin:
|
||||
return InferenceEngine::Precision::ePrecision::BIN;
|
||||
case cldnn::data_types::u8:
|
||||
return InferenceEngine::Precision::ePrecision::U8;
|
||||
case cldnn::data_types::i8:
|
||||
return InferenceEngine::Precision::ePrecision::I8;
|
||||
case cldnn::data_types::f16:
|
||||
return InferenceEngine::Precision::ePrecision::FP16;
|
||||
case cldnn::data_types::f32:
|
||||
return InferenceEngine::Precision::ePrecision::FP32;
|
||||
case cldnn::data_types::i32:
|
||||
return InferenceEngine::Precision::ePrecision::I32;
|
||||
case cldnn::data_types::i64:
|
||||
return InferenceEngine::Precision::ePrecision::I64;
|
||||
default:
|
||||
OPENVINO_THROW("The plugin does not support ", cldnn::data_type_traits::name(dt), " data type");
|
||||
inline ov::element::Type convert_to_supported_device_type(ov::element::Type et) {
|
||||
switch (et) {
|
||||
case ov::element::f64:
|
||||
case ov::element::i16:
|
||||
case ov::element::u16:
|
||||
return ov::element::f32;
|
||||
case ov::element::u64:
|
||||
case ov::element::u32:
|
||||
return ov::element::i32;
|
||||
default: return et;
|
||||
}
|
||||
}
|
||||
|
||||
inline cldnn::format FormatFromLayout(InferenceEngine::Layout l) {
|
||||
switch (l) {
|
||||
// TODO: change 6d case once new layout added in IE
|
||||
case InferenceEngine::Layout::BLOCKED:
|
||||
return cldnn::format::bfwzyx;
|
||||
case InferenceEngine::Layout::NCDHW:
|
||||
return cldnn::format::bfzyx;
|
||||
case InferenceEngine::Layout::NCHW:
|
||||
case InferenceEngine::Layout::NC:
|
||||
case InferenceEngine::Layout::CHW:
|
||||
case InferenceEngine::Layout::C:
|
||||
case InferenceEngine::Layout::SCALAR:
|
||||
return cldnn::format::bfyx;
|
||||
case InferenceEngine::Layout::NHWC:
|
||||
return cldnn::format::byxf;
|
||||
default:
|
||||
IE_THROW(ParameterMismatch) << "The plugin does not support " << l << " layout";
|
||||
}
|
||||
}
|
||||
|
||||
inline cldnn::format FormatFromTensorDesc(InferenceEngine::TensorDesc desc) {
|
||||
switch (desc.getLayout()) {
|
||||
case InferenceEngine::Layout::BLOCKED: {
|
||||
if (desc.getDims().size() == 6)
|
||||
return cldnn::format::bfwzyx;
|
||||
else if (desc.getDims().size() == 5)
|
||||
return cldnn::format::bfzyx;
|
||||
else if (desc.getDims().size() <= 4)
|
||||
return cldnn::format::bfyx;
|
||||
}
|
||||
case InferenceEngine::Layout::NCDHW:
|
||||
return cldnn::format::bfzyx;
|
||||
case InferenceEngine::Layout::NCHW:
|
||||
case InferenceEngine::Layout::NC:
|
||||
case InferenceEngine::Layout::CHW:
|
||||
case InferenceEngine::Layout::C:
|
||||
case InferenceEngine::Layout::SCALAR:
|
||||
return cldnn::format::bfyx;
|
||||
case InferenceEngine::Layout::NHWC:
|
||||
return cldnn::format::byxf;
|
||||
default:
|
||||
IE_THROW(ParameterMismatch)
|
||||
<< "The plugin does not support " << desc.getLayout() << " layout";
|
||||
}
|
||||
}
|
||||
|
||||
inline cldnn::format ImageFormatFromLayout(InferenceEngine::Layout l) {
|
||||
switch (l) {
|
||||
// currently, nv12 is the only supported image layout
|
||||
case InferenceEngine::Layout::BLOCKED:
|
||||
case InferenceEngine::Layout::NCDHW:
|
||||
case InferenceEngine::Layout::NCHW:
|
||||
case InferenceEngine::Layout::NC:
|
||||
case InferenceEngine::Layout::CHW:
|
||||
case InferenceEngine::Layout::C:
|
||||
case InferenceEngine::Layout::NHWC:
|
||||
return cldnn::format::nv12;
|
||||
default:
|
||||
IE_THROW(ParameterMismatch)
|
||||
<< "The plugin does not support " << l << " image layout";
|
||||
}
|
||||
}
|
||||
OPENVINO_SUPPRESS_DEPRECATED_END
|
||||
|
||||
/// WA: Force exit. Any opencl api call can be hang after CL_OUT_OF_RESOURCES.
|
||||
inline void ForceExit() {
|
||||
std::cerr << "[GPU] force exit.\n"
|
||||
@@ -156,4 +70,11 @@ inline void ForceExit() {
|
||||
}
|
||||
|
||||
} // namespace intel_gpu
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const ov::AnyMap& params) {
|
||||
for (const auto& p : params) {
|
||||
os << p.first << " : " << p.second.as<std::string>() << std::endl;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
} // namespace ov
|
||||
@@ -4,51 +4,70 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/runtime/icompiled_model.hpp"
|
||||
#include "intel_gpu/plugin/graph.hpp"
|
||||
#include "intel_gpu/plugin/plugin.hpp"
|
||||
#include "intel_gpu/plugin/remote_context.hpp"
|
||||
#include "intel_gpu/runtime/execution_config.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include "ie_blob.h"
|
||||
#include "cpp/ie_cnn_network.h"
|
||||
#include <cpp_interfaces/impl/ie_executable_network_thread_safe_default.hpp>
|
||||
#include "intel_gpu/plugin/graph.hpp"
|
||||
#include "intel_gpu/plugin/remote_context.hpp"
|
||||
#include "intel_gpu/runtime/execution_config.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
class CompiledModel : public InferenceEngine::ExecutableNetworkThreadSafeDefault {
|
||||
class CompiledModel : public ov::ICompiledModel {
|
||||
public:
|
||||
typedef std::shared_ptr<CompiledModel> Ptr;
|
||||
using Ptr = std::shared_ptr<CompiledModel>;
|
||||
|
||||
CompiledModel(InferenceEngine::CNNNetwork &network, InferenceEngine::RemoteContext::Ptr context, const ExecutionConfig& config,
|
||||
InferenceEngine::InputsDataMap* inputs = nullptr, InferenceEngine::OutputsDataMap* outputs = nullptr);
|
||||
CompiledModel(cldnn::BinaryInputBuffer& ib, InferenceEngine::RemoteContext::Ptr context, const ExecutionConfig& config,
|
||||
InferenceEngine::InputsDataMap* inputs = nullptr, InferenceEngine::OutputsDataMap* outputs = nullptr);
|
||||
CompiledModel(std::shared_ptr<ov::Model> model,
|
||||
const std::shared_ptr<const ov::IPlugin>& plugin,
|
||||
RemoteContextImpl::Ptr context,
|
||||
const ExecutionConfig& config);
|
||||
CompiledModel(cldnn::BinaryInputBuffer ib,
|
||||
const std::shared_ptr<const ov::IPlugin>& plugin,
|
||||
RemoteContextImpl::Ptr context,
|
||||
const ExecutionConfig& config);
|
||||
|
||||
void Export(std::ostream& networkModel) override;
|
||||
std::shared_ptr<ngraph::Function> GetExecGraphInfo() override;
|
||||
InferenceEngine::IInferRequestInternal::Ptr CreateInferRequest() override;
|
||||
InferenceEngine::IInferRequestInternal::Ptr CreateInferRequestImpl(InferenceEngine::InputsDataMap networkInputs,
|
||||
InferenceEngine::OutputsDataMap networkOutputs) override;
|
||||
InferenceEngine::IInferRequestInternal::Ptr CreateInferRequestImpl(const std::vector<std::shared_ptr<const ov::Node>>& inputs,
|
||||
const std::vector<std::shared_ptr<const ov::Node>>& outputs) override;
|
||||
template <class T>
|
||||
InferenceEngine::IInferRequestInternal::Ptr GetInferRequestImpl(const std::vector<std::shared_ptr<const ov::Node>>& inputs,
|
||||
const std::vector<std::shared_ptr<const ov::Node>>& outputs);
|
||||
InferenceEngine::Parameter GetMetric(const std::string &name) const override;
|
||||
InferenceEngine::Parameter GetConfig(const std::string &name) const override;
|
||||
std::shared_ptr<InferenceEngine::RemoteContext> GetContext() const override;
|
||||
std::shared_ptr<ov::IAsyncInferRequest> create_infer_request() const override;
|
||||
std::shared_ptr<ov::ISyncInferRequest> create_sync_infer_request() const override;
|
||||
|
||||
std::vector<std::shared_ptr<Graph>> m_graphs;
|
||||
InferenceEngine::RemoteContext::Ptr m_context;
|
||||
void export_model(std::ostream& model) const override;
|
||||
|
||||
std::shared_ptr<const ov::Model> get_runtime_model() const override;
|
||||
|
||||
ov::Any get_property(const std::string& name) const override;
|
||||
|
||||
void set_property(const ov::AnyMap& properties) override {
|
||||
OPENVINO_ASSERT_HELPER(::ov::NotImplemented,
|
||||
"",
|
||||
false,
|
||||
"Not Implemented: ",
|
||||
"CompiledModel::set_property is not supported by this plugin!");
|
||||
};
|
||||
|
||||
const std::vector<ov::Output<const ov::Node>>& outputs() const override { return m_outputs; }
|
||||
const std::vector<ov::Output<const ov::Node>>& inputs() const override { return m_inputs;}
|
||||
|
||||
bool is_new_api() const { return std::static_pointer_cast<const ov::intel_gpu::Plugin>(get_plugin())->is_new_api(); }
|
||||
RemoteContextImpl::Ptr get_context_impl() const {return m_context; }
|
||||
const std::vector<std::shared_ptr<Graph>>& get_graphs() const;
|
||||
std::shared_ptr<Graph> get_graph(size_t n) const;
|
||||
|
||||
private:
|
||||
RemoteContextImpl::Ptr m_context;
|
||||
ExecutionConfig m_config;
|
||||
InferenceEngine::ITaskExecutor::Ptr m_taskExecutor;
|
||||
InferenceEngine::ITaskExecutor::Ptr m_waitExecutor;
|
||||
InferenceEngine::CNNNetwork m_network;
|
||||
std::shared_ptr<ov::threading::ITaskExecutor> m_wait_executor;
|
||||
std::shared_ptr<ov::Model> m_model;
|
||||
std::string m_model_name;
|
||||
std::vector<ov::Output<const ov::Node>> m_inputs;
|
||||
std::vector<ov::Output<const ov::Node>> m_outputs;
|
||||
std::vector<std::shared_ptr<Graph>> m_graphs;
|
||||
bool m_loaded_from_cache;
|
||||
};
|
||||
|
||||
} // namespace intel_gpu
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
|
||||
#include "intel_gpu/graph/network.hpp"
|
||||
#include "intel_gpu/graph/topology.hpp"
|
||||
#include "intel_gpu/plugin/custom_layer.hpp"
|
||||
#include "intel_gpu/plugin/remote_context.hpp"
|
||||
#include "intel_gpu/plugin/program_builder.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
@@ -15,74 +21,48 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "ie_blob.h"
|
||||
#include "cpp/ie_cnn_network.h"
|
||||
|
||||
#include "intel_gpu/graph/network.hpp"
|
||||
#include "intel_gpu/graph/topology.hpp"
|
||||
|
||||
#include <cpp_interfaces/impl/ie_executable_network_thread_safe_default.hpp>
|
||||
#include "intel_gpu/plugin/custom_layer.hpp"
|
||||
#include "intel_gpu/plugin/remote_context.hpp"
|
||||
#include "intel_gpu/plugin/remote_blob.hpp"
|
||||
#include "intel_gpu/plugin/program_builder.hpp"
|
||||
#include <condition_variable>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
class Graph {
|
||||
class Graph final {
|
||||
public:
|
||||
using Ptr = std::shared_ptr<Graph>;
|
||||
enum class Stage : uint32_t {
|
||||
PREPROC = 1,
|
||||
EXECUTE = 2,
|
||||
POSTPROC = 4
|
||||
};
|
||||
typedef std::shared_ptr<Graph> Ptr;
|
||||
using variable_states_map = std::map<std::string, std::vector<cldnn::network::VariableState::Ptr>>;
|
||||
|
||||
Graph(InferenceEngine::CNNNetwork& network,
|
||||
const RemoteContextImpl::Ptr& context,
|
||||
const ExecutionConfig& config,
|
||||
uint16_t stream_id = 0,
|
||||
InferenceEngine::InputsDataMap* inputs = nullptr,
|
||||
InferenceEngine::OutputsDataMap* outputs = nullptr);
|
||||
Graph(cldnn::BinaryInputBuffer& ib,
|
||||
const RemoteContextImpl::Ptr& context,
|
||||
const ExecutionConfig& config,
|
||||
uint16_t stream_id = 0,
|
||||
InferenceEngine::InputsDataMap* inputs = nullptr,
|
||||
InferenceEngine::OutputsDataMap* outputs = nullptr);
|
||||
explicit Graph(std::shared_ptr<Graph> graph, uint16_t stream_id = 0);
|
||||
void Export(cldnn::BinaryOutputBuffer &ob);
|
||||
std::shared_ptr<ngraph::Function> GetExecGraphInfo();
|
||||
Graph(std::shared_ptr<ov::Model> model, const RemoteContextImpl::Ptr& context, const ExecutionConfig& config, uint16_t stream_id = 0);
|
||||
Graph(cldnn::BinaryInputBuffer& ib, const RemoteContextImpl::Ptr& context, const ExecutionConfig& config, uint16_t stream_id = 0);
|
||||
Graph(std::shared_ptr<Graph> graph, uint16_t stream_id = 0);
|
||||
|
||||
bool IsLoaded() const;
|
||||
void export_model(cldnn::BinaryOutputBuffer &ob);
|
||||
std::shared_ptr<ov::Model> get_runtime_model();
|
||||
|
||||
std::map<std::string, InferenceEngine::InferenceEngineProfileInfo> GetPerformanceCounts() const;
|
||||
void UpdatePerfStatistics();
|
||||
bool is_loaded() const;
|
||||
|
||||
std::vector<ov::ProfilingInfo> get_profiling_info() const;
|
||||
void update_profiling_info();
|
||||
|
||||
cldnn::engine& get_engine() const { return m_context->get_engine(); }
|
||||
const ExecutionConfig& get_config() const { return m_config; }
|
||||
|
||||
size_t GetMaxDynamicBatchSize() const { return m_config.get_property(ov::intel_gpu::max_dynamic_batch);}
|
||||
const std::map<std::string, cldnn::layout>& GetInputLayouts() const { return m_program->GetInputLayouts(); }
|
||||
const InferenceEngine::InputsDataMap GetNetworkInputs() const { return m_program->GetNetworkInputs(); }
|
||||
const InferenceEngine::OutputsDataMap GetNetworkOutputs() const { return m_program->GetNetworkOutputs(); }
|
||||
variable_states_map AllocateVariablesMemories();
|
||||
std::map<std::string, std::pair<int64_t, int64_t>> GetInputDynBatchDims() { return m_program->m_input_batch_dim; }
|
||||
std::map<std::string, int64_t> GetOutputDynBatchDims() { return m_program->m_output_batch_dim; }
|
||||
size_t GetNetworksCount() const { return m_networks.size(); }
|
||||
std::shared_ptr<cldnn::network> GetNetwork(size_t idx = 0) const;
|
||||
InferenceEngine::SizeVector GetOutputSize(std::string outName) const;
|
||||
std::string MapOutputName(std::string outName) const;
|
||||
std::string getName() const { return m_networkName; }
|
||||
const std::map<std::string, cldnn::layout>& get_input_layouts() const { return m_input_layouts; }
|
||||
std::shared_ptr<cldnn::network> get_network() const;
|
||||
|
||||
std::string out_name_to_internal(std::string out_port_name) const;
|
||||
|
||||
void wait(Stage stage_mask) {
|
||||
std::unique_lock<std::mutex> lock(m_infer_mutex);
|
||||
m_cv.wait(lock, [&] {
|
||||
m_cv.wait(lock, [&stage_mask, this] {
|
||||
return (m_state & (uint32_t)stage_mask) == 0;
|
||||
});
|
||||
m_state |= (uint32_t)stage_mask;
|
||||
}
|
||||
|
||||
void notify(Stage stage_mask) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_infer_mutex);
|
||||
@@ -94,30 +74,25 @@ public:
|
||||
|
||||
bool use_external_queue() const;
|
||||
|
||||
protected:
|
||||
private:
|
||||
RemoteContextImpl::Ptr m_context;
|
||||
std::shared_ptr<ProgramBuilder> m_program;
|
||||
std::string m_networkName;
|
||||
ExecutionConfig m_config;
|
||||
uint16_t m_stream_id;
|
||||
uint32_t m_state;
|
||||
uint32_t m_state = 0;
|
||||
std::condition_variable m_cv;
|
||||
std::mutex m_infer_mutex;
|
||||
|
||||
std::vector<std::shared_ptr<cldnn::network>> m_networks;
|
||||
std::shared_ptr<cldnn::network> m_network;
|
||||
std::map<std::string, cldnn::primitive_id> primitiveIDs;
|
||||
std::map<std::string, std::vector<cldnn::primitive_id>> prevPrimitiveIDs;
|
||||
|
||||
std::map<cldnn::primitive_id, std::pair<std::string, PerfCounter>> perfMap;
|
||||
std::vector<cldnn::primitive_id> profilingIDs;
|
||||
|
||||
std::map<std::string, InferenceEngine::SizeVector> outputDims;
|
||||
std::map<std::string, cldnn::layout> m_input_layouts;
|
||||
|
||||
std::shared_ptr<cldnn::network> BuildNetwork(std::shared_ptr<cldnn::program> program);
|
||||
void Build();
|
||||
void UpdateLayersMaps();
|
||||
std::shared_ptr<ngraph::Function> GetExecGraphInfoByPrimitivesInfo(std::vector<cldnn::primitive_info>& pi,
|
||||
bool filter_const_primitives = true);
|
||||
void build(std::shared_ptr<cldnn::program> program);
|
||||
std::shared_ptr<ov::Model> get_runtime_model(std::vector<cldnn::primitive_info>& pi, bool filter_const_primitives = true);
|
||||
};
|
||||
|
||||
} // namespace intel_gpu
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include "intel_gpu/plugin/graph.hpp"
|
||||
#include <threading/ie_istreams_executor.hpp>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
class CompiledModel;
|
||||
|
||||
class InferRequest : public InferenceEngine::IInferRequestInternal {
|
||||
public:
|
||||
using Ptr = std::shared_ptr<InferRequest>;
|
||||
// make sure all blobs and cldnn::memory objects
|
||||
// are in place and valid
|
||||
void checkBlobs() override;
|
||||
void InferImpl() override;
|
||||
|
||||
std::map<std::string, InferenceEngine::InferenceEngineProfileInfo> GetPerformanceCounts() const override;
|
||||
|
||||
InferRequest(InferenceEngine::InputsDataMap networkInputs, InferenceEngine::OutputsDataMap networkOutputs,
|
||||
const std::shared_ptr<CompiledModel>& execNetwork);
|
||||
InferRequest(const std::vector<std::shared_ptr<const ov::Node>>& inputs,
|
||||
const std::vector<std::shared_ptr<const ov::Node>>& outputs,
|
||||
const std::shared_ptr<CompiledModel>& execNetwork);
|
||||
|
||||
InferRequest(const InferRequest &) = delete;
|
||||
|
||||
virtual ~InferRequest() = default;
|
||||
|
||||
InferenceEngine::Blob::Ptr GetBlob(const std::string& name) override;
|
||||
void SetBlob(const std::string& name, const InferenceEngine::Blob::Ptr &data) override;
|
||||
void SetBlobs(const std::string& name, const std::vector<InferenceEngine::Blob::Ptr> &data) override;
|
||||
|
||||
std::vector<std::shared_ptr<InferenceEngine::IVariableStateInternal>> QueryState() override;
|
||||
void SetGraph(std::shared_ptr<Graph> graph);
|
||||
void EnableProfiling() { m_useProfiling = true; }
|
||||
void EnableStreams() { m_useStreams = true; }
|
||||
|
||||
void setup_stream_graph();
|
||||
void enqueue_notify();
|
||||
void wait_notify();
|
||||
|
||||
void enqueue();
|
||||
void wait();
|
||||
|
||||
bool use_external_queue() const { return m_useExternalQueue; }
|
||||
void enable_external_queue() { m_useExternalQueue = true; }
|
||||
|
||||
private:
|
||||
// This blob is used for outputs processing if output data type convertion or padding handling is needed
|
||||
InferenceEngine::Blob::Ptr intermediate_output_blob = nullptr;
|
||||
InferenceEngine::BlobMap users_blobs_matching;
|
||||
InferenceEngine::BlobMap _deviceOutputs;
|
||||
std::map<std::string, cldnn::primitive_id> inputsMap;
|
||||
std::map<std::string, cldnn::primitive_id> outputsMap;
|
||||
|
||||
std::map<std::string, std::vector<InferenceEngine::Blob::Ptr>> inputTensorsMap;
|
||||
|
||||
bool m_useProfiling = false;
|
||||
bool m_useStreams = false;
|
||||
bool m_useExternalQueue = false;
|
||||
std::shared_ptr<Graph> m_graph;
|
||||
InferenceEngine::gpu::ClContext::Ptr m_context = nullptr;
|
||||
|
||||
InferenceEngine::IStreamsExecutor* streamExecutor = nullptr;
|
||||
|
||||
void prepare_input(const cldnn::primitive_id &inputName, InferenceEngine::Blob::Ptr &inputBlob,
|
||||
std::vector<cldnn::event::ptr>& dependencies);
|
||||
void prepare_output(const cldnn::primitive_id& outputName, InferenceEngine::Blob::Ptr& outputBlob,
|
||||
std::vector<cldnn::event::ptr>& dependencies);
|
||||
void allocate_dev_mem_if_needed(InferenceEngine::BlobMap& device_mems, InferenceEngine::Blob::Ptr& user_blob,
|
||||
const cldnn::primitive_id& blob_name, const cldnn::layout& layout,
|
||||
const bool need_lockable_mem = false);
|
||||
|
||||
InferenceEngine::Blob::Ptr create_host_blob(const InferenceEngine::TensorDesc& desc, bool is_dynamic);
|
||||
InferenceEngine::Blob::Ptr create_device_blob(const InferenceEngine::TensorDesc& desc);
|
||||
|
||||
void copy_output_data(cldnn::memory::ptr outputMemory, InferenceEngine::Blob::Ptr bptr, std::vector<cldnn::event::ptr>& events);
|
||||
|
||||
template<typename RemoteBlobType, typename = typename std::enable_if<std::is_same<RemoteBlobType, RemoteCLbuffer>::value ||
|
||||
std::is_same<RemoteBlobType, RemoteUSMbuffer>::value>::type>
|
||||
InferenceEngine::Blob::Ptr create_remote_blob(const InferenceEngine::TensorDesc& desc, const cldnn::layout& layout,
|
||||
const BlobType mem_type, void* mem_ptr = nullptr);
|
||||
InferenceEngine::Blob::Ptr create_shared_device_blob(const InferenceEngine::TensorDesc& desc, const cldnn::layout& layout, void* usm_host_mem);
|
||||
void allocate_inputs();
|
||||
void allocate_outputs();
|
||||
|
||||
void set_input(const std::string& name, const InferenceEngine::Blob::Ptr& data);
|
||||
void set_output(const std::string& name, const InferenceEngine::Blob::Ptr& data);
|
||||
InferenceEngine::Blob::Ptr reinterpret_device_blob(InferenceEngine::Blob::Ptr data, const InferenceEngine::TensorDesc& new_desc);
|
||||
|
||||
std::map<cldnn::primitive_id, cldnn::network_output> internal_outputs;
|
||||
};
|
||||
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
@@ -1,115 +0,0 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include "intel_gpu/plugin/graph.hpp"
|
||||
#include <threading/ie_istreams_executor.hpp>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
struct buf_info {
|
||||
size_t buf_offset;
|
||||
size_t buf_size;
|
||||
};
|
||||
|
||||
class CompiledModel;
|
||||
|
||||
class InferRequestLegacy : public InferenceEngine::IInferRequestInternal {
|
||||
public:
|
||||
using Ptr = std::shared_ptr<InferRequestLegacy>;
|
||||
// make sure all blobs and cldnn::memory objects
|
||||
// are in place and valid
|
||||
void checkBlobs() override;
|
||||
void InferImpl() override;
|
||||
|
||||
std::map<std::string, InferenceEngine::InferenceEngineProfileInfo> GetPerformanceCounts() const override;
|
||||
|
||||
InferRequestLegacy(InferenceEngine::InputsDataMap networkInputs, InferenceEngine::OutputsDataMap networkOutputs,
|
||||
const std::shared_ptr<CompiledModel>& execNetwork);
|
||||
InferRequestLegacy(const std::vector<std::shared_ptr<const ov::Node>>& inputs,
|
||||
const std::vector<std::shared_ptr<const ov::Node>>& outputs,
|
||||
const std::shared_ptr<CompiledModel>& execNetwork);
|
||||
|
||||
InferRequestLegacy(const InferRequestLegacy &) = delete;
|
||||
|
||||
virtual ~InferRequestLegacy() = default;
|
||||
|
||||
InferenceEngine::Blob::Ptr GetBlob(const std::string& name) override;
|
||||
void SetBlob(const std::string& name, const InferenceEngine::Blob::Ptr &data) override;
|
||||
void SetBlobs(const std::string& name, const std::vector<InferenceEngine::Blob::Ptr> &data) override;
|
||||
|
||||
void SetBatch(int batch = -1);
|
||||
std::vector<std::shared_ptr<InferenceEngine::IVariableStateInternal>> QueryState() override;
|
||||
void SetGraph(std::shared_ptr<Graph> graph);
|
||||
void EnableProfiling() { m_useProfiling = true; }
|
||||
void EnableStreams() { m_useStreams = true; }
|
||||
|
||||
void setup_stream_graph();
|
||||
void preprocess_notify();
|
||||
void enqueue_notify();
|
||||
void wait_notify();
|
||||
|
||||
void preprocess();
|
||||
void enqueue();
|
||||
void wait();
|
||||
|
||||
void preprocess_dynamic();
|
||||
void enqueue_dynamic();
|
||||
void wait_dynamic();
|
||||
|
||||
bool use_external_queue() const { return m_useExternalQueue; }
|
||||
void enable_external_queue() { m_useExternalQueue = true; }
|
||||
|
||||
private:
|
||||
InferenceEngine::BlobMap _deviceOutputs;
|
||||
std::map<std::string, cldnn::primitive_id> inputsMap;
|
||||
std::map<std::string, cldnn::primitive_id> outputsMap;
|
||||
|
||||
std::map<std::string, std::vector<InferenceEngine::Blob::Ptr>> inputTensorsMap;
|
||||
|
||||
bool m_useProfiling = false;
|
||||
bool m_useStreams = false;
|
||||
bool m_useExternalQueue = false;
|
||||
std::shared_ptr<Graph> m_graph;
|
||||
InferenceEngine::gpu::ClContext::Ptr m_context = nullptr;
|
||||
|
||||
// dynamic batch stuff
|
||||
std::map<std::string, std::vector<buf_info>> batchInputs;
|
||||
std::map<std::string, std::vector<buf_info>> batchOutputs;
|
||||
InferenceEngine::IStreamsExecutor* streamExecutor = nullptr;
|
||||
|
||||
void prepare_input(const cldnn::primitive_id &inputName, InferenceEngine::Blob::Ptr &inputBlob,
|
||||
std::vector<cldnn::event::ptr>& dependencies);
|
||||
void prepare_output(const cldnn::primitive_id& outputName, InferenceEngine::Blob::Ptr& outputBlob);
|
||||
|
||||
InferenceEngine::Blob::Ptr create_host_blob(const InferenceEngine::TensorDesc& desc,
|
||||
std::shared_ptr<InferenceEngine::IAllocator> alloc = nullptr);
|
||||
InferenceEngine::Blob::Ptr create_device_blob(const InferenceEngine::TensorDesc& desc, const cldnn::layout& layout);
|
||||
|
||||
void copy_output_data(cldnn::memory::ptr outputMemory, InferenceEngine::Blob::Ptr bptr, buf_info* bi = nullptr);
|
||||
void copy_input_data(std::shared_ptr<cldnn::network> network, const cldnn::primitive_id &inputName,
|
||||
const cldnn::layout& inputLayout, const InferenceEngine::Blob &inputBlob,
|
||||
buf_info* bi = nullptr);
|
||||
|
||||
InferenceEngine::Blob::Ptr create_shared_device_blob(const InferenceEngine::TensorDesc& desc, const cldnn::layout& layout, void* usm_host_mem);
|
||||
void allocate_inputs();
|
||||
void allocate_outputs();
|
||||
void allocate_inputs_dynamic();
|
||||
void allocate_outputs_dynamic();
|
||||
|
||||
std::map<cldnn::primitive_id, cldnn::network_output> internal_outputs;
|
||||
std::vector<std::map<cldnn::primitive_id, cldnn::network_output>> internal_outputs_dynamic;
|
||||
Graph::variable_states_map variables_states_;
|
||||
int m_curBatch = -1;
|
||||
};
|
||||
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include "intel_gpu/runtime/execution_config.hpp"
|
||||
#include "ie_metric_helpers.hpp"
|
||||
#include <ie_ngraph_utils.hpp>
|
||||
#include "ie_plugin_config.hpp"
|
||||
#include "gpu/gpu_config.hpp"
|
||||
#include "cpp_interfaces/interface/ie_internal_plugin_config.hpp"
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
// Copyright (C) 2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "intel_gpu/plugin/remote_tensor.hpp"
|
||||
#include <remote_utils.hpp>
|
||||
|
||||
#ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <gpu/gpu_context_api_dx.hpp>
|
||||
#else
|
||||
# include <gpu/gpu_context_api_va.hpp>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
class RemoteAllocator : public InferenceEngine::IAllocator {
|
||||
protected:
|
||||
friend class RemoteTensorImpl;
|
||||
RemoteTensorImpl* m_tensor = nullptr;
|
||||
|
||||
mutable std::mutex locked_mutex;
|
||||
mutable size_t locked_counter = 0;
|
||||
mutable std::unique_ptr<cldnn::mem_lock<uint8_t>> locked_holder = nullptr;
|
||||
mutable void* _handle = nullptr;
|
||||
|
||||
public:
|
||||
using Ptr = std::shared_ptr<RemoteAllocator>;
|
||||
|
||||
RemoteAllocator(RemoteTensorImpl* tensor) : m_tensor(tensor) { }
|
||||
/**
|
||||
* @brief Maps handle to heap memory accessible by any memory manipulation routines.
|
||||
* @return Generic pointer to memory
|
||||
*/
|
||||
void* lock(void* handle, InferenceEngine::LockOp = InferenceEngine::LOCK_FOR_WRITE) noexcept override {
|
||||
try {
|
||||
std::lock_guard<std::mutex> locker(locked_mutex);
|
||||
if (locked_counter == 0) {
|
||||
auto mem = m_tensor->get_original_memory();
|
||||
auto& stream = mem->get_engine()->get_service_stream();
|
||||
locked_holder = std::unique_ptr<cldnn::mem_lock<uint8_t>>(new cldnn::mem_lock<uint8_t>(mem, stream));
|
||||
_handle = reinterpret_cast<void*>(locked_holder->data());
|
||||
}
|
||||
locked_counter++;
|
||||
|
||||
return _handle;
|
||||
} catch (std::exception&) {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @brief Unmaps memory by handle with multiple sequential mappings of the same handle.
|
||||
* The multiple sequential mappings of the same handle are suppose to get the same
|
||||
* result while there isn't a ref counter supported.
|
||||
*/
|
||||
void unlock(void* handle) noexcept override {
|
||||
std::lock_guard<std::mutex> locker(locked_mutex);
|
||||
locked_counter--;
|
||||
if (locked_counter == 0)
|
||||
locked_holder.reset();
|
||||
}
|
||||
/**
|
||||
* @brief Allocates memory
|
||||
* @param size The size in bytes to allocate
|
||||
* @return Handle to the allocated resource
|
||||
*/
|
||||
void* alloc(size_t size) noexcept override { return nullptr; }
|
||||
/**
|
||||
* @brief Releases handle and all associated memory resources which invalidates the handle.
|
||||
* @return false if handle cannot be released, otherwise - true.
|
||||
*/
|
||||
bool free(void* handle) noexcept override { return true; }
|
||||
};
|
||||
|
||||
template<typename TpublicAPI>
|
||||
class TypedRemoteBlob : public TpublicAPI, public ov::legacy_convert::TensorHolder {
|
||||
public:
|
||||
using Ptr = std::shared_ptr<TypedRemoteBlob>;
|
||||
|
||||
explicit TypedRemoteBlob(std::shared_ptr<RemoteTensorImpl> impl, InferenceEngine::gpu::ClContext::Ptr context)
|
||||
: TpublicAPI(InferenceEngine::TensorDesc(InferenceEngine::details::convertPrecision(impl->get_element_type()),
|
||||
impl->get_shape(),
|
||||
InferenceEngine::TensorDesc::getLayoutByDims(impl->get_shape())))
|
||||
, ov::legacy_convert::TensorHolder({impl, nullptr})
|
||||
, m_impl(impl)
|
||||
, m_context(context)
|
||||
, m_allocator(std::make_shared<RemoteAllocator>(impl.get())) { }
|
||||
|
||||
void allocate() noexcept override { }
|
||||
bool deallocate() noexcept override { return true; }
|
||||
InferenceEngine::ParamMap getParams() const override { return m_impl->get_properties(); }
|
||||
|
||||
std::string getDeviceName() const noexcept override { return m_impl->get_device_name(); }
|
||||
|
||||
std::shared_ptr<InferenceEngine::RemoteContext> getContext() const noexcept override { return m_context; }
|
||||
InferenceEngine::LockedMemory<void> buffer() noexcept override {
|
||||
return InferenceEngine::LockedMemory<void>(m_allocator.get(), m_impl.get(), 0);
|
||||
}
|
||||
InferenceEngine::LockedMemory<const void> cbuffer() const noexcept override {
|
||||
return InferenceEngine::LockedMemory<const void>(m_allocator.get(), m_impl.get(), 0);
|
||||
}
|
||||
InferenceEngine::LockedMemory<void> rwmap() noexcept override {
|
||||
return InferenceEngine::LockedMemory<void>(m_allocator.get(), m_impl.get(), 0);
|
||||
}
|
||||
InferenceEngine::LockedMemory<const void> rmap() const noexcept override {
|
||||
return InferenceEngine::LockedMemory<const void>(m_allocator.get(), m_impl.get(), 0);
|
||||
}
|
||||
InferenceEngine::LockedMemory<void> wmap() noexcept override {
|
||||
return InferenceEngine::LockedMemory<void>(m_allocator.get(), m_impl.get(), 0);
|
||||
}
|
||||
void setShape(const InferenceEngine::SizeVector& dims) override { m_impl->set_shape(dims); }
|
||||
|
||||
|
||||
private:
|
||||
const std::shared_ptr<InferenceEngine::IAllocator> &getAllocator() const noexcept override { return m_allocator; }
|
||||
void *getHandle() const noexcept override { return m_handle; }
|
||||
|
||||
std::shared_ptr<RemoteTensorImpl> m_impl;
|
||||
std::shared_ptr<InferenceEngine::gpu::ClContext> m_context;
|
||||
void* m_handle = nullptr;
|
||||
std::shared_ptr<InferenceEngine::IAllocator> m_allocator;
|
||||
};
|
||||
|
||||
using RemoteCLbuffer = TypedRemoteBlob<InferenceEngine::gpu::ClBufferBlob>;
|
||||
using RemoteUSMbuffer = TypedRemoteBlob<InferenceEngine::gpu::USMBlob>;
|
||||
using RemoteCLImage2D = TypedRemoteBlob<InferenceEngine::gpu::ClImage2DBlob>;
|
||||
#ifdef _WIN32
|
||||
using RemoteD3DBuffer = TypedRemoteBlob<InferenceEngine::gpu::D3DBufferBlob>;
|
||||
using RemoteD3DSurface = TypedRemoteBlob<InferenceEngine::gpu::D3DSurface2DBlob>;
|
||||
#else
|
||||
using RemoteVASurface = TypedRemoteBlob<InferenceEngine::gpu::VASurfaceBlob>;
|
||||
#endif
|
||||
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
@@ -0,0 +1,152 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "intel_gpu/runtime/memory.hpp"
|
||||
#include "intel_gpu/runtime/engine.hpp"
|
||||
#include "intel_gpu/runtime/lru_cache.hpp"
|
||||
#include "intel_gpu/plugin/common_utils.hpp"
|
||||
#include "intel_gpu/plugin/remote_context.hpp"
|
||||
#include "intel_gpu/plugin/legacy_remote_blob.hpp"
|
||||
|
||||
#include <ie_parameter.hpp>
|
||||
#include <blob_factory.hpp>
|
||||
#include <ie_remote_context.hpp>
|
||||
#include <remote_utils.hpp>
|
||||
|
||||
#ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <gpu/gpu_context_api_dx.hpp>
|
||||
#else
|
||||
# include <gpu/gpu_context_api_va.hpp>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
|
||||
// Template class below is needed to allow proper cast of user contexts
|
||||
// We have the following public classes hierarchy:
|
||||
// RemoteContext
|
||||
// |
|
||||
// ClContext
|
||||
// | |
|
||||
// VAContext D3DContext
|
||||
// So our implementation must allow casting of context object to proper type user type (ClContext, VAContext or D3DContext)
|
||||
// Thus we introduce this template which have 3 instances with different base classes:
|
||||
// RemoteContext
|
||||
// |
|
||||
// ---------- ClContext -----------
|
||||
// | | |
|
||||
// VAContext | D3DContext
|
||||
// | | |
|
||||
// RemoteVAContext RemoteCLContext RemoteD3DContext
|
||||
//
|
||||
// All these context types are just thin wrappers that calls common context internal impl (RemoteContextImpl)
|
||||
template<typename PublicContextType>
|
||||
class TypedRemoteContext : public PublicContextType {
|
||||
public:
|
||||
using Ptr = std::shared_ptr<TypedRemoteContext>;
|
||||
|
||||
explicit TypedRemoteContext(std::shared_ptr<RemoteContextImpl> impl) : m_impl(impl) {}
|
||||
TypedRemoteContext(std::string device_name, std::vector<cldnn::device::ptr> devices)
|
||||
: m_impl(std::make_shared<RemoteContextImpl>(device_name, devices)) {}
|
||||
TypedRemoteContext(const std::map<std::string, RemoteContextImpl::Ptr>& known_contexts, const InferenceEngine::ParamMap& params)
|
||||
: m_impl(std::make_shared<RemoteContextImpl>(known_contexts, params)) {}
|
||||
|
||||
InferenceEngine::ParamMap getParams() const override { return m_impl->get_property(); }
|
||||
std::string getDeviceName() const noexcept override { return m_impl->get_device_name(); }
|
||||
InferenceEngine::MemoryBlob::Ptr CreateHostBlob(const InferenceEngine::TensorDesc& desc) override {
|
||||
auto new_tensor = m_impl->create_host_tensor(InferenceEngine::details::convertPrecision(desc.getPrecision()), ov::Shape(desc.getDims()));
|
||||
return std::dynamic_pointer_cast<InferenceEngine::MemoryBlob>(make_blob_with_precision(desc, new_tensor->data()));
|
||||
}
|
||||
InferenceEngine::RemoteBlob::Ptr CreateBlob(const InferenceEngine::TensorDesc& desc, const InferenceEngine::ParamMap& params = {}) override {
|
||||
auto new_tensor = m_impl->create_tensor(InferenceEngine::details::convertPrecision(desc.getPrecision()), ov::Shape(desc.getDims()), params);
|
||||
auto tensor_impl = std::dynamic_pointer_cast<RemoteTensorImpl>(new_tensor._ptr);
|
||||
OPENVINO_ASSERT(tensor_impl, "[GPU] Unexpected tensor impl type");
|
||||
auto mem_type = tensor_impl->get_properties().at(ov::intel_gpu::shared_mem_type.name()).as<ov::intel_gpu::SharedMemType>();
|
||||
if (mem_type == ov::intel_gpu::SharedMemType::OCL_BUFFER) {
|
||||
return std::make_shared<RemoteCLbuffer>(tensor_impl, std::dynamic_pointer_cast<InferenceEngine::gpu::ClContext>(this->shared_from_this()));
|
||||
} else if (mem_type == ov::intel_gpu::SharedMemType::USM_DEVICE_BUFFER ||
|
||||
mem_type == ov::intel_gpu::SharedMemType::USM_HOST_BUFFER ||
|
||||
mem_type == ov::intel_gpu::SharedMemType::USM_USER_BUFFER) {
|
||||
return std::make_shared<RemoteUSMbuffer>(tensor_impl, std::dynamic_pointer_cast<InferenceEngine::gpu::ClContext>(this->shared_from_this()));
|
||||
} else if (mem_type == ov::intel_gpu::SharedMemType::OCL_IMAGE2D) {
|
||||
return std::make_shared<RemoteCLImage2D>(tensor_impl, std::dynamic_pointer_cast<InferenceEngine::gpu::ClContext>(this->shared_from_this()));
|
||||
#ifdef _WIN32
|
||||
} else if (mem_type == ov::intel_gpu::SharedMemType::DX_BUFFER) {
|
||||
return std::make_shared<RemoteD3DBuffer>(tensor_impl, std::dynamic_pointer_cast<InferenceEngine::gpu::ClContext>(this->shared_from_this()));
|
||||
} else if (mem_type == ov::intel_gpu::SharedMemType::VA_SURFACE) {
|
||||
return std::make_shared<RemoteD3DSurface>(tensor_impl, std::dynamic_pointer_cast<InferenceEngine::gpu::ClContext>(this->shared_from_this()));
|
||||
#else
|
||||
} else if (mem_type == ov::intel_gpu::SharedMemType::VA_SURFACE) {
|
||||
return std::make_shared<RemoteVASurface>(tensor_impl, std::dynamic_pointer_cast<InferenceEngine::gpu::ClContext>(this->shared_from_this()));
|
||||
#endif
|
||||
}
|
||||
OPENVINO_THROW("[GPU] CreateBlob error: Unsupported memory type: ", mem_type);
|
||||
}
|
||||
|
||||
RemoteContextImpl::Ptr get_impl() { return m_impl; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<RemoteContextImpl> m_impl;
|
||||
};
|
||||
|
||||
using RemoteCLContext = TypedRemoteContext<InferenceEngine::gpu::ClContext>;
|
||||
#ifdef _WIN32
|
||||
using RemoteD3DContext = TypedRemoteContext<InferenceEngine::gpu::D3DContext>;
|
||||
#else
|
||||
using RemoteVAContext = TypedRemoteContext<InferenceEngine::gpu::VAContext>;
|
||||
#endif
|
||||
|
||||
inline ov::SoPtr<ov::IRemoteContext> wrap_if_old_api(std::shared_ptr<RemoteContextImpl> new_impl, bool is_new_api) {
|
||||
if (is_new_api) {
|
||||
return new_impl;
|
||||
} else {
|
||||
auto remote_properties = new_impl->get_property();
|
||||
auto context_type = remote_properties.at(ov::intel_gpu::context_type.name()).as<ov::intel_gpu::ContextType>();
|
||||
if (context_type == ov::intel_gpu::ContextType::OCL) {
|
||||
return ov::legacy_convert::convert_remote_context(std::make_shared<RemoteCLContext>(new_impl));
|
||||
} else if (context_type == ov::intel_gpu::ContextType::VA_SHARED) {
|
||||
#ifdef _WIN32
|
||||
return ov::legacy_convert::convert_remote_context(std::make_shared<RemoteD3DContext>(new_impl));
|
||||
#else
|
||||
return ov::legacy_convert::convert_remote_context(std::make_shared<RemoteVAContext>(new_impl));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
OPENVINO_THROW("[GPU] Unexpected context parameters");
|
||||
}
|
||||
|
||||
|
||||
inline RemoteContextImpl::Ptr get_context_impl(ov::SoPtr<ov::IRemoteContext> ptr) {
|
||||
if (auto wrapper = std::dynamic_pointer_cast<InferenceEngine::IRemoteContextWrapper>(ptr._ptr)) {
|
||||
auto legacy_context = wrapper->get_context();
|
||||
if (auto legacy_context_impl = std::dynamic_pointer_cast<RemoteCLContext>(legacy_context)) {
|
||||
return legacy_context_impl->get_impl();
|
||||
#ifdef _WIN32
|
||||
} else if (auto legacy_context_impl = std::dynamic_pointer_cast<RemoteD3DContext>(legacy_context)) {
|
||||
return legacy_context_impl->get_impl();
|
||||
#else
|
||||
} else if (auto legacy_context_impl = std::dynamic_pointer_cast<RemoteVAContext>(legacy_context)) {
|
||||
return legacy_context_impl->get_impl();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
auto casted = std::dynamic_pointer_cast<RemoteContextImpl>(ptr._ptr);
|
||||
OPENVINO_ASSERT(casted, "[GPU] Invalid remote context type. Can't cast to ov::intel_gpu::RemoteContext type");
|
||||
return casted;
|
||||
}
|
||||
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
@@ -4,70 +4,64 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/runtime/iplugin.hpp"
|
||||
#include "intel_gpu/plugin/remote_context.hpp"
|
||||
#include "intel_gpu/runtime/engine.hpp"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "intel_gpu/runtime/engine.hpp"
|
||||
#include <cpp_interfaces/interface/ie_iplugin_internal.hpp>
|
||||
#include <cpp_interfaces/interface/ie_iexecutable_network_internal.hpp>
|
||||
#include "intel_gpu/plugin/remote_context.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
class Plugin : public InferenceEngine::IInferencePlugin {
|
||||
struct impl;
|
||||
std::shared_ptr<impl> _impl;
|
||||
|
||||
std::string default_device_id = "0";
|
||||
// key: device_id, value: cldnn device
|
||||
std::map<std::string, cldnn::device::ptr> device_map;
|
||||
class Plugin : public ov::IPlugin {
|
||||
private:
|
||||
std::string m_default_device_id = "0";
|
||||
std::map<std::string, cldnn::device::ptr> m_device_map;
|
||||
std::map<std::string, ExecutionConfig> m_configs_map;
|
||||
|
||||
mutable std::map<std::string, RemoteCLContext::Ptr> m_default_contexts;
|
||||
mutable std::map<std::string, std::shared_ptr<RemoteContextImpl>> m_default_contexts;
|
||||
mutable std::once_flag m_default_contexts_once;
|
||||
|
||||
std::map<std::string, RemoteCLContext::Ptr> get_default_contexts() const;
|
||||
std::map<std::string, std::shared_ptr<RemoteContextImpl>> get_default_contexts() const;
|
||||
|
||||
InferenceEngine::CNNNetwork clone_and_transform_model(const InferenceEngine::CNNNetwork& network,
|
||||
const ExecutionConfig& config) const;
|
||||
std::shared_ptr<ov::Model> clone_and_transform_model(const std::shared_ptr<const ov::Model>& network, const ExecutionConfig& config) const;
|
||||
void transform_model(std::shared_ptr<ov::Model>& model, const ExecutionConfig& config) const;
|
||||
void register_primitives();
|
||||
std::string get_device_id_from_config(const std::map<std::string, std::string>& config) const;
|
||||
std::string get_device_id(const std::map<std::string, std::string>& config) const;
|
||||
RemoteCLContext::Ptr get_default_context(const std::string& device_id) const;
|
||||
void register_primitives() const;
|
||||
std::string get_device_id_from_config(const ov::AnyMap& config) const;
|
||||
std::string get_device_id(const ov::AnyMap& config) const;
|
||||
std::shared_ptr<RemoteContextImpl> get_default_context(const std::string& device_id) const;
|
||||
|
||||
std::vector<ov::PropertyName> get_caching_properties() const;
|
||||
std::vector<ov::PropertyName> get_supported_properties() const;
|
||||
std::vector<ov::PropertyName> get_supported_internal_properties() const;
|
||||
std::vector<std::string> get_device_capabilities(const cldnn::device_info& info) const;
|
||||
uint32_t get_optimal_batch_size(const std::map<std::string, InferenceEngine::Parameter>& options) const;
|
||||
uint32_t get_max_batch_size(const std::map<std::string, InferenceEngine::Parameter>& options) const;
|
||||
uint32_t get_optimal_batch_size(const ov::AnyMap& options) const;
|
||||
uint32_t get_max_batch_size(const ov::AnyMap& options) const;
|
||||
|
||||
ov::AnyMap preprocess_config(const std::map<std::string, std::string>& orig_config) const;
|
||||
ov::AnyMap preprocess_config(const ov::AnyMap& orig_config) const;
|
||||
bool is_metric(const std::string& name) const;
|
||||
ov::Any get_metric(const std::string& name, const ov::AnyMap& arguments) const;
|
||||
|
||||
public:
|
||||
Plugin();
|
||||
|
||||
InferenceEngine::IExecutableNetworkInternal::Ptr LoadExeNetworkImpl(const InferenceEngine::CNNNetwork &network,
|
||||
const std::map<std::string, std::string> &config) override;
|
||||
std::shared_ptr<ov::ICompiledModel> compile_model(const std::shared_ptr<const ov::Model>& model,
|
||||
const ov::AnyMap& properties) const override;
|
||||
std::shared_ptr<ov::ICompiledModel> compile_model(const std::shared_ptr<const ov::Model>& model,
|
||||
const ov::AnyMap& properties,
|
||||
const ov::SoPtr<ov::IRemoteContext>& context) const override;
|
||||
|
||||
InferenceEngine::IExecutableNetworkInternal::Ptr LoadExeNetworkImpl(const InferenceEngine::CNNNetwork &network,
|
||||
const std::shared_ptr<InferenceEngine::RemoteContext> &context,
|
||||
const std::map<std::string, std::string> &config) override;
|
||||
|
||||
void SetConfig(const std::map<std::string, std::string> &config) override;
|
||||
InferenceEngine::Parameter GetConfig(const std::string& name, const std::map<std::string, InferenceEngine::Parameter>& options) const override;
|
||||
InferenceEngine::Parameter GetMetric(const std::string& name, const std::map<std::string, InferenceEngine::Parameter>& options) const override;
|
||||
InferenceEngine::QueryNetworkResult QueryNetwork(const InferenceEngine::CNNNetwork& network,
|
||||
const std::map<std::string, std::string>& config) const override;
|
||||
InferenceEngine::IExecutableNetworkInternal::Ptr ImportNetwork(std::istream& networkModel,
|
||||
const std::map<std::string, std::string>& config) override;
|
||||
InferenceEngine::IExecutableNetworkInternal::Ptr ImportNetwork(std::istream& networkModel,
|
||||
const std::shared_ptr<InferenceEngine::RemoteContext>& context,
|
||||
const std::map<std::string, std::string>& config) override;
|
||||
|
||||
std::shared_ptr<InferenceEngine::RemoteContext> CreateContext(const InferenceEngine::ParamMap& params) override;
|
||||
std::shared_ptr<InferenceEngine::RemoteContext> GetDefaultContext(const InferenceEngine::ParamMap& params) override;
|
||||
void set_property(const ov::AnyMap& properties) override;
|
||||
ov::Any get_property(const std::string& name, const ov::AnyMap& arguments) const override;
|
||||
std::shared_ptr<ov::ICompiledModel> import_model(std::istream& model, const ov::AnyMap& properties) const override;
|
||||
std::shared_ptr<ov::ICompiledModel> import_model(std::istream& model,
|
||||
const ov::SoPtr<ov::IRemoteContext>& context,
|
||||
const ov::AnyMap& properties) const override;
|
||||
ov::SupportedOpsMap query_model(const std::shared_ptr<const ov::Model>& model,
|
||||
const ov::AnyMap& properties) const override;
|
||||
ov::SoPtr<ov::IRemoteContext> create_context(const ov::AnyMap& remote_properties) const override;
|
||||
ov::SoPtr<ov::IRemoteContext> get_default_context(const ov::AnyMap& remote_properties) const override;
|
||||
};
|
||||
|
||||
} // namespace intel_gpu
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#include "intel_gpu/graph/topology.hpp"
|
||||
#include "intel_gpu/graph/program.hpp"
|
||||
|
||||
#include <cpp/ie_cnn_network.h>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
@@ -59,38 +57,28 @@ std::string layer_type_lower(const std::shared_ptr<ov::Node>& op);
|
||||
std::string layer_type_name_ID(const std::shared_ptr<ov::Node>& op);
|
||||
|
||||
struct PerfCounter {
|
||||
InferenceEngine::InferenceEngineProfileInfo::LayerStatus status;
|
||||
bool isCPU;
|
||||
uint64_t realTime_uSec;
|
||||
uint64_t cpu_uSec;
|
||||
uint32_t num;
|
||||
std::string layerType;
|
||||
std::string parentPrimitive;
|
||||
ov::ProfilingInfo::Status status = ov::ProfilingInfo::Status::NOT_RUN;
|
||||
bool isCPU = false;
|
||||
uint64_t realTime_uSec = 0;
|
||||
uint64_t cpu_uSec = 0;
|
||||
uint32_t num = 0;
|
||||
std::string layerType = "";
|
||||
std::string parentPrimitive = "";
|
||||
|
||||
public:
|
||||
PerfCounter()
|
||||
: status(InferenceEngine::InferenceEngineProfileInfo::NOT_RUN)
|
||||
, isCPU(false)
|
||||
, realTime_uSec(0)
|
||||
, cpu_uSec(0)
|
||||
, num(0) {}
|
||||
PerfCounter() = default;
|
||||
|
||||
long long realTime_avg() const { return (num == 0) ? 0 : realTime_uSec / num; }
|
||||
long long cpu_avg() const { return (num == 0) ? 0 : cpu_uSec / num; }
|
||||
};
|
||||
|
||||
class ProgramBuilder {
|
||||
class ProgramBuilder final {
|
||||
public:
|
||||
ProgramBuilder(InferenceEngine::CNNNetwork& network, cldnn::engine& engine, const ExecutionConfig& config,
|
||||
ProgramBuilder(std::shared_ptr<ov::Model> model, cldnn::engine& engine, const ExecutionConfig& config,
|
||||
bool createTopologyOnly = false, bool partialBuild = false,
|
||||
InferenceEngine::InputsDataMap* inputs = nullptr, InferenceEngine::OutputsDataMap* outputs = nullptr,
|
||||
std::shared_ptr<ov::threading::IStreamsExecutor> task_executor = nullptr, bool innerProgram = false);
|
||||
ProgramBuilder(cldnn::engine& engine, const ExecutionConfig& config,
|
||||
InferenceEngine::InputsDataMap* inputs = nullptr, InferenceEngine::OutputsDataMap* outputs = nullptr);
|
||||
ProgramBuilder(cldnn::engine& engine, const ExecutionConfig& config);
|
||||
|
||||
static const cldnn::primitive_id m_preProcessTag;
|
||||
static const cldnn::primitive_id m_meanValuesTag;
|
||||
static const cldnn::primitive_id m_workaroundTag;
|
||||
static const cldnn::primitive_id m_preCustomLayerTag;
|
||||
static const cldnn::primitive_id m_postCustomLayerTag;
|
||||
|
||||
@@ -100,38 +88,27 @@ public:
|
||||
|
||||
std::vector<cldnn::primitive_id> profiling_ids;
|
||||
|
||||
std::map<std::string, InferenceEngine::SizeVector> outputDims;
|
||||
std::map<std::string, cldnn::layout> inputLayouts;
|
||||
using BlobCacheKey = std::pair<const char*, std::vector<size_t>>;
|
||||
std::map<BlobCacheKey, cldnn::primitive_id> blobMemCache;
|
||||
CustomLayerMap m_custom_layers;
|
||||
|
||||
int m_max_batch;
|
||||
int m_curBatch;
|
||||
std::map<std::string, std::pair<int64_t, int64_t>> m_input_batch_dim;
|
||||
std::map<std::string, int64_t> m_output_batch_dim;
|
||||
std::shared_ptr<cldnn::program> get_compiled_program() const;
|
||||
std::shared_ptr<cldnn::topology> get_topology() const { return m_topology; }
|
||||
|
||||
std::shared_ptr<cldnn::program> GetCompiledProgram(int program_id = 0);
|
||||
const std::map<std::string, cldnn::layout>& GetInputLayouts() const { return inputLayouts; }
|
||||
InferenceEngine::InputsDataMap GetNetworkInputs() const { return m_networkInputs; }
|
||||
InferenceEngine::OutputsDataMap GetNetworkOutputs() const { return m_networkOutputs; }
|
||||
const std::map<std::string, cldnn::layout>& get_input_layouts() const { return inputLayouts; }
|
||||
cldnn::engine& get_engine() const { return m_engine; }
|
||||
const ExecutionConfig& get_config() const { return m_config; }
|
||||
int GetMaxBatchSizeForSingleProgram();
|
||||
|
||||
bool IsOpSupported(const InferenceEngine::CNNNetwork& network, const std::shared_ptr<ngraph::Node>& op);
|
||||
bool IsDynBatchModel(const std::shared_ptr<ov::Model>& model,
|
||||
std::map<std::string, ov::PartialShape>& shapes,
|
||||
std::map<std::string, std::pair<int64_t, int64_t>>& batch_dim);
|
||||
bool is_op_supported(const std::shared_ptr<ov::Node>& op);
|
||||
|
||||
// Profiling utils
|
||||
void init_profile_info(const cldnn::primitive& prim);
|
||||
|
||||
// Graph construction helpers
|
||||
std::vector<cldnn::input_info> GetInputInfo(const std::shared_ptr<ngraph::Node>& op) const;
|
||||
std::vector<cldnn::input_info> GetInputInfo(const std::shared_ptr<ov::Node>& op) const;
|
||||
|
||||
using factory_t = std::function<void(ProgramBuilder&, const std::shared_ptr<ngraph::Node>&)>;
|
||||
using factories_map_t = std::map<ngraph::DiscreteTypeInfo, factory_t>;
|
||||
using factory_t = std::function<void(ProgramBuilder&, const std::shared_ptr<ov::Node>&)>;
|
||||
using factories_map_t = std::map<ov::DiscreteTypeInfo, factory_t>;
|
||||
|
||||
template<typename OpType>
|
||||
static void RegisterFactory(factory_t func) {
|
||||
@@ -142,13 +119,12 @@ public:
|
||||
}
|
||||
|
||||
template<typename PType, typename = typename std::enable_if<!is_smart_pointer<PType>::value>::type>
|
||||
void add_primitive(const ngraph::Node& op, PType prim, std::vector<std::string> aliases = {}) {
|
||||
void add_primitive(const ov::Node& op, PType prim, std::vector<std::string> aliases = {}) {
|
||||
add_primitive(op, std::static_pointer_cast<cldnn::primitive>(std::make_shared<PType>(prim)), std::move(aliases));
|
||||
}
|
||||
|
||||
void add_primitive(const ngraph::Node& op, std::shared_ptr<cldnn::primitive> prim, std::vector<std::string> aliases = {});
|
||||
void add_primitive(const ov::Node& op, std::shared_ptr<cldnn::primitive> prim, std::vector<std::string> aliases = {});
|
||||
|
||||
std::shared_ptr<cldnn::topology> GetTopology() const { return m_topology; }
|
||||
|
||||
using variables_state_info_map = std::map<std::string, std::set<cldnn::layout>>;
|
||||
|
||||
@@ -157,21 +133,20 @@ public:
|
||||
const variables_state_info_map& GetVariablesStatesInfo() const { return m_variablesStateInfo; }
|
||||
|
||||
bool use_new_shape_infer() const { return allow_new_shape_infer; }
|
||||
bool requires_new_shape_infer(const ngraph::Node& op) const;
|
||||
bool requires_new_shape_infer(const ov::Node& op) const;
|
||||
|
||||
std::shared_ptr<ov::threading::IStreamsExecutor> get_task_executor() { return m_task_executor; }
|
||||
std::shared_ptr<ov::threading::IStreamsExecutor> get_task_executor() const { return m_task_executor; }
|
||||
|
||||
private:
|
||||
static factories_map_t factories_map;
|
||||
std::vector<std::shared_ptr<cldnn::program>> m_programs;
|
||||
std::shared_ptr<cldnn::program> m_program;
|
||||
ExecutionConfig m_config;
|
||||
cldnn::engine& m_engine;
|
||||
static std::mutex m_mutex;
|
||||
|
||||
std::shared_ptr<cldnn::topology> m_topology;
|
||||
InferenceEngine::InputsDataMap m_networkInputs;
|
||||
InferenceEngine::OutputsDataMap m_networkOutputs;
|
||||
variables_state_info_map m_variablesStateInfo;
|
||||
CustomLayerMap m_custom_layers;
|
||||
|
||||
bool allow_new_shape_infer = false;
|
||||
|
||||
@@ -182,31 +157,28 @@ private:
|
||||
void EnableQueryMode() { queryMode = true; }
|
||||
void DisableQueryMode() { queryMode = false; }
|
||||
|
||||
void PrepareBuild(InferenceEngine::InputsDataMap networkInputs, InferenceEngine::OutputsDataMap networkOutputs);
|
||||
void CleanupBuild();
|
||||
void prepare_build();
|
||||
void cleanup_build();
|
||||
|
||||
// TODO(eunsoo): remove createTopolpgyOnly argument and add another method to create topology from ngraph function
|
||||
std::shared_ptr<cldnn::program> BuildProgram(const std::vector<std::shared_ptr<ngraph::Node>>& ops,
|
||||
InferenceEngine::InputsDataMap networkInputs,
|
||||
InferenceEngine::OutputsDataMap networkOutputs,
|
||||
bool createTopologyOnly = false, bool partialBuild = false, bool innerProgram = false);
|
||||
std::shared_ptr<cldnn::program> build(const std::vector<std::shared_ptr<ov::Node>>& ops,
|
||||
bool createTopologyOnly = false, bool partialBuild = false, bool innerProgram = false);
|
||||
|
||||
void CreateSingleLayerPrimitive(cldnn::topology& topology, const std::shared_ptr<ngraph::Node>& op);
|
||||
void ChangeInputBatch(int batch);
|
||||
void CreateSingleLayerPrimitive(cldnn::topology& topology, const std::shared_ptr<ov::Node>& op);
|
||||
};
|
||||
|
||||
void CreateCustomOp(ProgramBuilder& p, const std::shared_ptr<ngraph::Node>& node, CustomLayerPtr customLayer);
|
||||
void CreateUnaryEltwiseOp(ProgramBuilder& p, const std::shared_ptr<ngraph::Node>& node,
|
||||
void CreateCustomOp(ProgramBuilder& p, const std::shared_ptr<ov::Node>& node, CustomLayerPtr customLayer);
|
||||
void CreateUnaryEltwiseOp(ProgramBuilder& p, const std::shared_ptr<ov::Node>& node,
|
||||
cldnn::activation_func func, cldnn::activation_additional_params params);
|
||||
void CreateElementwiseOp(ProgramBuilder& p,
|
||||
const std::shared_ptr<ngraph::Node>& node,
|
||||
const std::shared_ptr<ov::Node>& node,
|
||||
cldnn::eltwise_mode mode,
|
||||
std::vector<float> coefficients = {},
|
||||
bool pythondiv = true);
|
||||
|
||||
bool IsNodeOnConstPath(const std::shared_ptr<ngraph::Node>& node);
|
||||
bool IsNodeOnConstPath(const std::shared_ptr<ov::Node>& node);
|
||||
|
||||
void validate_inputs_count(const std::shared_ptr<ngraph::Node>& op, std::vector<size_t> possible_inputs_count);
|
||||
void validate_inputs_count(const std::shared_ptr<ov::Node>& op, std::vector<size_t> possible_inputs_count);
|
||||
|
||||
inline bool ends_with(const std::string& value, const std::string& suffix) {
|
||||
if (suffix.size() > value.size())
|
||||
|
||||
@@ -4,95 +4,39 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "intel_gpu/plugin/remote_context.hpp"
|
||||
#include "openvino/runtime/so_ptr.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
class RemoteBlobImpl;
|
||||
class RemoteTensorImpl;
|
||||
class RemoteContextImpl;
|
||||
|
||||
class RemoteAllocator : public InferenceEngine::IAllocator {
|
||||
protected:
|
||||
friend class RemoteBlobImpl;
|
||||
std::atomic_flag _lock;
|
||||
std::map<void*, const RemoteBlobImpl*> m_lockedBlobs;
|
||||
|
||||
void regLockedBlob(void* handle, const RemoteBlobImpl* blob);
|
||||
|
||||
public:
|
||||
using Ptr = std::shared_ptr<RemoteAllocator>;
|
||||
|
||||
RemoteAllocator() { _lock.clear(std::memory_order_relaxed); }
|
||||
/**
|
||||
* @brief Maps handle to heap memory accessible by any memory manipulation routines.
|
||||
* @return Generic pointer to memory
|
||||
*/
|
||||
void* lock(void* handle, InferenceEngine::LockOp = InferenceEngine::LOCK_FOR_WRITE) noexcept override { return handle; };
|
||||
/**
|
||||
* @brief Unmaps memory by handle with multiple sequential mappings of the same handle.
|
||||
* The multiple sequential mappings of the same handle are suppose to get the same
|
||||
* result while there isn't a ref counter supported.
|
||||
*/
|
||||
void unlock(void* handle) noexcept override;
|
||||
/**
|
||||
* @brief Allocates memory
|
||||
* @param size The size in bytes to allocate
|
||||
* @return Handle to the allocated resource
|
||||
*/
|
||||
void* alloc(size_t size) noexcept override { return nullptr; }
|
||||
/**
|
||||
* @brief Releases handle and all associated memory resources which invalidates the handle.
|
||||
* @return false if handle cannot be released, otherwise - true.
|
||||
*/
|
||||
bool free(void* handle) noexcept override { return true; }
|
||||
|
||||
void lock() {
|
||||
while (_lock.test_and_set(std::memory_order_acquire)) {}
|
||||
}
|
||||
|
||||
void unlock() {
|
||||
_lock.clear(std::memory_order_release);
|
||||
}
|
||||
};
|
||||
|
||||
class USMHostAllocator : public InferenceEngine::IAllocator {
|
||||
protected:
|
||||
InferenceEngine::gpu::USMBlob::Ptr _usm_host_blob = nullptr;
|
||||
InferenceEngine::gpu::ClContext::Ptr _context = nullptr;
|
||||
class USMHostAllocator final {
|
||||
private:
|
||||
ov::SoPtr<RemoteTensorImpl> _usm_host_tensor = { nullptr, nullptr };
|
||||
std::shared_ptr<RemoteContextImpl> _context = nullptr;
|
||||
|
||||
public:
|
||||
using Ptr = std::shared_ptr<USMHostAllocator>;
|
||||
|
||||
USMHostAllocator(InferenceEngine::gpu::ClContext::Ptr context) : _context(context) { }
|
||||
/**
|
||||
* @brief Maps handle to heap memory accessible by any memory manipulation routines.
|
||||
* @return Generic pointer to memory
|
||||
*/
|
||||
void* lock(void* handle, InferenceEngine::LockOp = InferenceEngine::LOCK_FOR_WRITE) noexcept override;
|
||||
|
||||
/**
|
||||
* @brief Unmaps memory by handle with multiple sequential mappings of the same handle.
|
||||
* The multiple sequential mappings of the same handle are suppose to get the same
|
||||
* result while there isn't a ref counter supported.
|
||||
*/
|
||||
void unlock(void* handle) noexcept override;
|
||||
explicit USMHostAllocator(std::shared_ptr<RemoteContextImpl> context) : _context(context) { }
|
||||
|
||||
/**
|
||||
* @brief Allocates memory
|
||||
* @param size The size in bytes to allocate
|
||||
* @return Handle to the allocated resource
|
||||
*/
|
||||
void* alloc(size_t size) noexcept override;
|
||||
void* allocate(const size_t bytes, const size_t alignment = alignof(max_align_t)) noexcept;
|
||||
/**
|
||||
* @brief Releases handle and all associated memory resources which invalidates the handle.
|
||||
* @return false if handle cannot be released, otherwise - true.
|
||||
*/
|
||||
bool free(void* handle) noexcept override;
|
||||
bool deallocate(void* handle, const size_t bytes, size_t alignment = alignof(max_align_t)) noexcept;
|
||||
|
||||
bool is_equal(const USMHostAllocator& other) const;
|
||||
};
|
||||
|
||||
} // namespace intel_gpu
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
// Copyright (C) 2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "intel_gpu/runtime/memory.hpp"
|
||||
#include "intel_gpu/runtime/engine.hpp"
|
||||
#include "intel_gpu/plugin/common_utils.hpp"
|
||||
|
||||
#ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <gpu/gpu_context_api_dx.hpp>
|
||||
#else
|
||||
# include <gpu/gpu_context_api_va.hpp>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
class RemoteContextImpl;
|
||||
|
||||
class RemoteBlobImpl : public InferenceEngine::gpu::details::param_map_obj_getter {
|
||||
friend class RemoteAllocator;
|
||||
public:
|
||||
explicit RemoteBlobImpl(InferenceEngine::gpu::ClContext::Ptr context,
|
||||
cldnn::stream& stream,
|
||||
const cldnn::layout& layout,
|
||||
cldnn::shared_handle mem = nullptr,
|
||||
cldnn::shared_surface surf = 0,
|
||||
uint32_t plane = 0,
|
||||
BlobType mem_type = BlobType::BT_BUF_INTERNAL);
|
||||
|
||||
void allocate();
|
||||
bool deallocate() noexcept;
|
||||
InferenceEngine::ParamMap getParams() const;
|
||||
std::string getDeviceName() const noexcept;
|
||||
std::shared_ptr<InferenceEngine::RemoteContext> getContext() const noexcept;
|
||||
InferenceEngine::LockedMemory<void> buffer() noexcept;
|
||||
InferenceEngine::LockedMemory<const void> cbuffer() const noexcept;
|
||||
InferenceEngine::LockedMemory<void> rwmap() noexcept;
|
||||
InferenceEngine::LockedMemory<const void> rmap() const noexcept;
|
||||
InferenceEngine::LockedMemory<void> wmap() noexcept;
|
||||
const std::shared_ptr<InferenceEngine::IAllocator> &getAllocator() const noexcept;
|
||||
void *getHandle() const noexcept { return _handle; }
|
||||
|
||||
void reinterpret(const cldnn::layout& new_layout);
|
||||
|
||||
bool is_allocated() const noexcept;
|
||||
bool is_locked() const noexcept;
|
||||
cldnn::memory::ptr get_memory() {
|
||||
auto engine = m_memory_object->get_engine();
|
||||
return engine->reinterpret_buffer(*m_memory_object, m_layout);
|
||||
}
|
||||
cldnn::memory::ptr get_original_memory() {
|
||||
return m_memory_object;
|
||||
}
|
||||
void setShape(const InferenceEngine::SizeVector& dims);
|
||||
|
||||
protected:
|
||||
std::shared_ptr<InferenceEngine::IAllocator> m_allocator;
|
||||
InferenceEngine::gpu::ClContext::Ptr m_context;
|
||||
cldnn::stream& m_stream;
|
||||
|
||||
// constructor stuff
|
||||
cldnn::shared_handle m_mem;
|
||||
cldnn::shared_surface m_surf;
|
||||
|
||||
uint32_t m_plane;
|
||||
cldnn::layout m_layout;
|
||||
BlobType m_mem_type;
|
||||
size_t m_hash;
|
||||
|
||||
cldnn::memory::ptr m_memory_object;
|
||||
|
||||
mutable std::mutex lockedMutex;
|
||||
mutable size_t lockedCounter;
|
||||
mutable std::unique_ptr<cldnn::mem_lock<uint8_t>> lockedHolder;
|
||||
mutable void* _handle;
|
||||
|
||||
void lock() const;
|
||||
void unlock() const;
|
||||
|
||||
bool is_shared() const;
|
||||
bool supports_caching() const;
|
||||
};
|
||||
|
||||
template<typename TpublicAPI>
|
||||
class TypedRemoteBlob : public TpublicAPI {
|
||||
public:
|
||||
using Ptr = std::shared_ptr<TypedRemoteBlob>;
|
||||
|
||||
explicit TypedRemoteBlob(InferenceEngine::gpu::ClContext::Ptr context,
|
||||
cldnn::stream& stream,
|
||||
const InferenceEngine::TensorDesc& desc,
|
||||
const cldnn::layout& layout,
|
||||
cldnn::shared_handle mem = nullptr,
|
||||
cldnn::shared_surface surf = 0,
|
||||
uint32_t plane = 0,
|
||||
BlobType mem_type = BlobType::BT_BUF_INTERNAL)
|
||||
: TpublicAPI(desc)
|
||||
, _impl(context, stream, layout, mem, surf, plane, mem_type) {}
|
||||
|
||||
void allocate() noexcept override {
|
||||
try {
|
||||
if (!_impl.is_allocated())
|
||||
_impl.allocate();
|
||||
} catch (...) {}
|
||||
}
|
||||
bool deallocate() noexcept override { return _impl.deallocate(); }
|
||||
InferenceEngine::ParamMap getParams() const override { return _impl.getParams(); }
|
||||
std::string getDeviceName() const noexcept override { return _impl.getDeviceName(); }
|
||||
std::shared_ptr<InferenceEngine::RemoteContext> getContext() const noexcept override { return _impl.getContext(); }
|
||||
InferenceEngine::LockedMemory<void> buffer() noexcept override { return _impl.buffer(); }
|
||||
InferenceEngine::LockedMemory<const void> cbuffer() const noexcept override { return _impl.cbuffer(); }
|
||||
InferenceEngine::LockedMemory<void> rwmap() noexcept override { return _impl.rwmap(); }
|
||||
InferenceEngine::LockedMemory<const void> rmap() const noexcept override { return _impl.rmap(); }
|
||||
InferenceEngine::LockedMemory<void> wmap()noexcept override { return _impl.wmap(); }
|
||||
RemoteBlobImpl* getImpl() { return &_impl; }
|
||||
void setShape(const InferenceEngine::SizeVector& dims) override { _impl.setShape(dims); }
|
||||
|
||||
protected:
|
||||
const std::shared_ptr<InferenceEngine::IAllocator> &getAllocator() const noexcept override { return _impl.getAllocator(); }
|
||||
void *getHandle() const noexcept override { return _impl.getHandle(); }
|
||||
RemoteBlobImpl _impl;
|
||||
};
|
||||
|
||||
using RemoteCLbuffer = TypedRemoteBlob<InferenceEngine::gpu::ClBufferBlob>;
|
||||
using RemoteUSMbuffer = TypedRemoteBlob<InferenceEngine::gpu::USMBlob>;
|
||||
using RemoteCLImage2D = TypedRemoteBlob<InferenceEngine::gpu::ClImage2DBlob>;
|
||||
#ifdef _WIN32
|
||||
using RemoteD3DBuffer = TypedRemoteBlob<InferenceEngine::gpu::D3DBufferBlob>;
|
||||
using RemoteD3DSurface = TypedRemoteBlob<InferenceEngine::gpu::D3DSurface2DBlob>;
|
||||
#else
|
||||
using RemoteVASurface = TypedRemoteBlob<InferenceEngine::gpu::VASurfaceBlob>;
|
||||
#endif
|
||||
|
||||
inline RemoteBlobImpl* getBlobImpl(InferenceEngine::gpu::ClBlob* blobPtr) {
|
||||
#ifdef _WIN32
|
||||
{
|
||||
auto ptr = blobPtr->as<RemoteD3DSurface>();
|
||||
if (ptr) return ptr->getImpl();
|
||||
}
|
||||
{
|
||||
auto ptr = blobPtr->as<RemoteD3DBuffer>();
|
||||
if (ptr) return ptr->getImpl();
|
||||
}
|
||||
#else
|
||||
{
|
||||
auto ptr = blobPtr->as<RemoteVASurface>();
|
||||
if (ptr) return ptr->getImpl();
|
||||
}
|
||||
#endif
|
||||
{
|
||||
auto ptr = blobPtr->as<RemoteCLbuffer>();
|
||||
if (ptr) return ptr->getImpl();
|
||||
}
|
||||
{
|
||||
auto ptr = blobPtr->as<RemoteCLImage2D>();
|
||||
if (ptr) return ptr->getImpl();
|
||||
}
|
||||
{
|
||||
auto ptr = blobPtr->as<RemoteUSMbuffer>();
|
||||
if (ptr) return ptr->getImpl();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
@@ -4,25 +4,23 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "intel_gpu/runtime/memory.hpp"
|
||||
#include "intel_gpu/runtime/engine.hpp"
|
||||
#include "intel_gpu/runtime/lru_cache.hpp"
|
||||
#include "intel_gpu/plugin/common_utils.hpp"
|
||||
|
||||
#include <ie_parameter.hpp>
|
||||
#include <cpp_interfaces/interface/ie_iplugin_internal.hpp>
|
||||
#include <blob_factory.hpp>
|
||||
#include <ie_remote_context.hpp>
|
||||
|
||||
#ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <gpu/gpu_context_api_dx.hpp>
|
||||
# include <openvino/runtime/intel_gpu/ocl/dx.hpp>
|
||||
#else
|
||||
# include <gpu/gpu_context_api_va.hpp>
|
||||
# include <openvino/runtime/intel_gpu/ocl/va.hpp>
|
||||
#endif
|
||||
#include "openvino/runtime/iremote_context.hpp"
|
||||
|
||||
#include "intel_gpu/runtime/memory.hpp"
|
||||
#include "intel_gpu/runtime/engine.hpp"
|
||||
#include "intel_gpu/runtime/lru_cache.hpp"
|
||||
#include "intel_gpu/plugin/common_utils.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
@@ -32,150 +30,50 @@
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
enum class BlobType {
|
||||
BT_EMPTY,
|
||||
BT_BUF_INTERNAL,
|
||||
BT_BUF_SHARED,
|
||||
BT_USM_SHARED,
|
||||
BT_USM_HOST_INTERNAL,
|
||||
BT_USM_DEVICE_INTERNAL,
|
||||
BT_IMG_SHARED,
|
||||
BT_SURF_SHARED,
|
||||
BT_DX_BUF_SHARED,
|
||||
};
|
||||
|
||||
template <typename Result>
|
||||
Result extract_object(const InferenceEngine::ParamMap& params, const std::string& key) {
|
||||
auto itrHandle = params.find(key);
|
||||
OPENVINO_ASSERT(itrHandle != params.end(), "[GPU] No parameter ", key, " found in ParamsMap");
|
||||
return itrHandle->second.as<Result>();
|
||||
}
|
||||
|
||||
class RemoteContextImpl {
|
||||
class RemoteContextImpl : public ov::IRemoteContext {
|
||||
public:
|
||||
enum ContextType {
|
||||
OCL,
|
||||
DEV_SHARED
|
||||
};
|
||||
|
||||
using Ptr = std::shared_ptr<RemoteContextImpl>;
|
||||
using CPtr = std::shared_ptr<const RemoteContextImpl>;
|
||||
|
||||
RemoteContextImpl(std::string device_name, std::vector<cldnn::device::ptr> devices);
|
||||
RemoteContextImpl(const std::vector<RemoteContextImpl::Ptr>& known_contexts, const InferenceEngine::ParamMap& params);
|
||||
RemoteContextImpl(const std::string& device_name, std::vector<cldnn::device::ptr> devices);
|
||||
RemoteContextImpl(const std::map<std::string, RemoteContextImpl::Ptr>& known_contexts, const ov::AnyMap& params);
|
||||
|
||||
const std::string& get_device_name() const override;
|
||||
|
||||
const ov::AnyMap& get_property() const override;
|
||||
ov::SoPtr<ov::ITensor> create_host_tensor(const ov::element::Type type, const ov::Shape& shape) override;
|
||||
ov::SoPtr<ov::IRemoteTensor> create_tensor(const ov::element::Type& type, const ov::Shape& shape, const ov::AnyMap& params) override;
|
||||
|
||||
InferenceEngine::ParamMap get_params() const;
|
||||
std::string get_device_name() const noexcept;
|
||||
InferenceEngine::MemoryBlob::Ptr create_host_blob(InferenceEngine::gpu::ClContext::Ptr public_context, const InferenceEngine::TensorDesc& desc);
|
||||
InferenceEngine::RemoteBlob::Ptr create_blob(InferenceEngine::gpu::ClContext::Ptr public_context,
|
||||
const InferenceEngine::TensorDesc& desc,
|
||||
const InferenceEngine::ParamMap& params = {});
|
||||
|
||||
cldnn::engine& get_engine() { return *m_engine; }
|
||||
InferenceEngine::gpu_handle_param get_external_queue() const { return m_external_queue; }
|
||||
ov::intel_gpu::gpu_handle_param get_external_queue() const { return m_external_queue; }
|
||||
|
||||
cldnn::memory::ptr try_get_cached_memory(size_t hash);
|
||||
void add_to_cache(size_t hash, cldnn::memory::ptr memory);
|
||||
|
||||
private:
|
||||
std::string get_device_name(const std::vector<RemoteContextImpl::Ptr>& known_contexts,
|
||||
const cldnn::device::ptr current_device);
|
||||
InferenceEngine::RemoteBlob::Ptr reuse_surface(InferenceEngine::gpu::ClContext::Ptr public_context,
|
||||
const InferenceEngine::TensorDesc& desc,
|
||||
const InferenceEngine::ParamMap& params);
|
||||
InferenceEngine::RemoteBlob::Ptr reuse_memory(InferenceEngine::gpu::ClContext::Ptr public_context,
|
||||
const InferenceEngine::TensorDesc& desc,
|
||||
cldnn::shared_handle mem,
|
||||
BlobType blob_type);
|
||||
InferenceEngine::RemoteBlob::Ptr create_buffer(InferenceEngine::gpu::ClContext::Ptr public_context, const InferenceEngine::TensorDesc& desc);
|
||||
InferenceEngine::RemoteBlob::Ptr create_usm(InferenceEngine::gpu::ClContext::Ptr public_context,
|
||||
const InferenceEngine::TensorDesc& desc,
|
||||
BlobType alloc_type);
|
||||
void check_if_shared();
|
||||
std::shared_ptr<RemoteContextImpl> get_this_shared_ptr();
|
||||
|
||||
std::string get_device_name(const std::map<std::string, RemoteContextImpl::Ptr>& known_contexts, const cldnn::device::ptr current_device) const;
|
||||
std::shared_ptr<ov::IRemoteTensor> reuse_surface(const ov::element::Type type, const ov::Shape& shape, const ov::AnyMap& params);
|
||||
std::shared_ptr<ov::IRemoteTensor> reuse_memory(const ov::element::Type type, const ov::Shape& shape, cldnn::shared_handle mem, TensorType tensor_type);
|
||||
std::shared_ptr<ov::IRemoteTensor> create_buffer(const ov::element::Type type, const ov::Shape& shape);
|
||||
std::shared_ptr<ov::IRemoteTensor> create_usm(const ov::element::Type type, const ov::Shape& shape, TensorType alloc_type);
|
||||
void check_if_shared() const;
|
||||
|
||||
void init_properties();
|
||||
|
||||
std::shared_ptr<cldnn::engine> m_engine;
|
||||
InferenceEngine::gpu_handle_param m_va_display;
|
||||
InferenceEngine::gpu_handle_param m_external_queue;
|
||||
static const size_t cache_capacity = 100;
|
||||
ov::intel_gpu::gpu_handle_param m_va_display = nullptr;
|
||||
ov::intel_gpu::gpu_handle_param m_external_queue = nullptr;
|
||||
|
||||
ContextType m_type;
|
||||
ContextType m_type = ContextType::OCL;
|
||||
std::string m_device_name = "";
|
||||
const std::string m_plugin_name;
|
||||
cldnn::LruCache<size_t, cldnn::memory::ptr> m_memory_cache;
|
||||
static const size_t cache_capacity = 100;
|
||||
cldnn::LruCache<size_t, cldnn::memory::ptr> m_memory_cache = cldnn::LruCache<size_t, cldnn::memory::ptr>(cache_capacity);
|
||||
std::mutex m_cache_mutex;
|
||||
|
||||
ov::AnyMap properties;
|
||||
};
|
||||
|
||||
// Template class below is needed to allow proper cast of user contexts
|
||||
// We have the following public classes hierarchy:
|
||||
// RemoteContext
|
||||
// |
|
||||
// ClContext
|
||||
// | |
|
||||
// VAContext D3DContext
|
||||
// So our implementation must allow casting of context object to proper type user type (ClContext, VAContext or D3DContext)
|
||||
// Thus we introduce this template which have 3 instances with different base classes:
|
||||
// RemoteContext
|
||||
// |
|
||||
// ---------- ClContext -----------
|
||||
// | | |
|
||||
// VAContext | D3DContext
|
||||
// | | |
|
||||
// RemoteVAContext RemoteCLContext RemoteD3DContext
|
||||
//
|
||||
// All these context types are just thin wrappers that calls common context internal impl (RemoteContextImpl)
|
||||
template<typename PublicContextType>
|
||||
class TypedRemoteContext : public PublicContextType {
|
||||
public:
|
||||
using Ptr = std::shared_ptr<TypedRemoteContext>;
|
||||
|
||||
TypedRemoteContext(std::string device_name, std::vector<cldnn::device::ptr> devices)
|
||||
: m_impl(std::make_shared<RemoteContextImpl>(device_name, devices)) {}
|
||||
TypedRemoteContext(const std::vector<RemoteContextImpl::Ptr>& known_contexts, const InferenceEngine::ParamMap& params)
|
||||
: m_impl(std::make_shared<RemoteContextImpl>(known_contexts, params)) {}
|
||||
|
||||
InferenceEngine::ParamMap getParams() const override { return m_impl->get_params(); }
|
||||
std::string getDeviceName() const noexcept override { return m_impl->get_device_name(); }
|
||||
InferenceEngine::MemoryBlob::Ptr CreateHostBlob(const InferenceEngine::TensorDesc& desc) override {
|
||||
return m_impl->create_host_blob(std::dynamic_pointer_cast<InferenceEngine::gpu::ClContext>(this->shared_from_this()), desc);
|
||||
}
|
||||
InferenceEngine::RemoteBlob::Ptr CreateBlob(const InferenceEngine::TensorDesc& desc, const InferenceEngine::ParamMap& params = {}) override {
|
||||
return m_impl->create_blob(std::dynamic_pointer_cast<InferenceEngine::gpu::ClContext>(this->shared_from_this()), desc, params);
|
||||
}
|
||||
|
||||
RemoteContextImpl::Ptr get_impl() { return m_impl; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<RemoteContextImpl> m_impl;
|
||||
};
|
||||
|
||||
using RemoteCLContext = TypedRemoteContext<InferenceEngine::gpu::ClContext>;
|
||||
#ifdef _WIN32
|
||||
using RemoteD3DContext = TypedRemoteContext<InferenceEngine::gpu::D3DContext>;
|
||||
#else
|
||||
using RemoteVAContext = TypedRemoteContext<InferenceEngine::gpu::VAContext>;
|
||||
#endif
|
||||
|
||||
inline std::shared_ptr<RemoteContextImpl> get_context_impl(InferenceEngine::gpu::ClContext::Ptr context) {
|
||||
OPENVINO_ASSERT(context != nullptr, "[GPU] Couldn't get impl from invalid context object");
|
||||
#ifdef _WIN32
|
||||
if (auto ptr = context->as<RemoteD3DContext>())
|
||||
return ptr->get_impl();
|
||||
#else
|
||||
if (auto ptr = context->as<RemoteVAContext>())
|
||||
return ptr->get_impl();
|
||||
#endif
|
||||
if (auto ptr = context->as<RemoteCLContext>())
|
||||
return ptr->get_impl();
|
||||
|
||||
OPENVINO_ASSERT(false, "[GPU] Couldn't get context impl from public context object.");
|
||||
}
|
||||
|
||||
inline std::shared_ptr<RemoteContextImpl> get_context_impl(InferenceEngine::RemoteContext::Ptr context) {
|
||||
OPENVINO_ASSERT(context != nullptr, "[GPU] Couldn't get impl from invalid context object");
|
||||
auto casted = std::dynamic_pointer_cast<InferenceEngine::gpu::ClContext>(context);
|
||||
OPENVINO_ASSERT(casted != nullptr, "[GPU] Couldn't get context impl: Context type is not ClContext or it's derivatives");
|
||||
return get_context_impl(casted);
|
||||
}
|
||||
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
@@ -0,0 +1,84 @@
|
||||
// Copyright (C) 2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <openvino/runtime/intel_gpu/ocl/dx.hpp>
|
||||
#else
|
||||
# include <openvino/runtime/intel_gpu/ocl/va.hpp>
|
||||
#endif
|
||||
#include "openvino/runtime/iremote_tensor.hpp"
|
||||
|
||||
#include "intel_gpu/runtime/memory.hpp"
|
||||
#include "intel_gpu/runtime/engine.hpp"
|
||||
#include "intel_gpu/plugin/common_utils.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
class RemoteContextImpl;
|
||||
|
||||
class RemoteTensorImpl : public ov::IRemoteTensor {
|
||||
friend class RemoteAllocator;
|
||||
public:
|
||||
RemoteTensorImpl(std::shared_ptr<RemoteContextImpl> context,
|
||||
const ov::Shape& shape,
|
||||
const ov::element::Type& element_type,
|
||||
TensorType mem_type = TensorType::BT_BUF_INTERNAL,
|
||||
cldnn::shared_handle mem = nullptr,
|
||||
cldnn::shared_surface surf = 0,
|
||||
uint32_t plane = 0);
|
||||
|
||||
~RemoteTensorImpl() override;
|
||||
const AnyMap& get_properties() const override;
|
||||
const std::string& get_device_name() const override;
|
||||
|
||||
void set_shape(ov::Shape shape) override;
|
||||
const ov::element::Type& get_element_type() const override;
|
||||
const ov::Shape& get_shape() const override;
|
||||
const ov::Strides& get_strides() const override;
|
||||
|
||||
void allocate();
|
||||
bool deallocate() noexcept;
|
||||
|
||||
bool is_allocated() const noexcept;
|
||||
bool is_surface() const noexcept;
|
||||
cldnn::memory::ptr get_memory() const;
|
||||
cldnn::memory::ptr get_original_memory() const;
|
||||
|
||||
std::shared_ptr<RemoteContextImpl> get_context() const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<RemoteContextImpl> m_context;
|
||||
|
||||
ov::element::Type m_element_type;
|
||||
ov::Shape m_shape;
|
||||
ov::Strides m_strides{};
|
||||
ov::AnyMap m_properties;
|
||||
|
||||
cldnn::memory::ptr m_memory_object = nullptr;
|
||||
cldnn::layout m_layout;
|
||||
TensorType m_mem_type;
|
||||
|
||||
cldnn::shared_handle m_mem;
|
||||
cldnn::shared_surface m_surf;
|
||||
uint32_t m_plane;
|
||||
size_t m_hash = 0;
|
||||
|
||||
bool is_shared() const;
|
||||
bool supports_caching() const;
|
||||
void update_strides();
|
||||
void init_properties();
|
||||
};
|
||||
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
@@ -0,0 +1,109 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openvino/runtime/isync_infer_request.hpp"
|
||||
#include "intel_gpu/plugin/graph.hpp"
|
||||
#include "intel_gpu/plugin/remote_tensor.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
class CompiledModel;
|
||||
|
||||
enum class TensorOwner : uint8_t {
|
||||
USER = 0,
|
||||
PLUGIN = 1
|
||||
};
|
||||
|
||||
struct TensorWrapper {
|
||||
std::shared_ptr<ov::ITensor> ptr;
|
||||
TensorOwner owner;
|
||||
};
|
||||
|
||||
class SyncInferRequest : public ov::ISyncInferRequest {
|
||||
public:
|
||||
using Ptr = std::shared_ptr<SyncInferRequest>;
|
||||
|
||||
explicit SyncInferRequest(const std::shared_ptr<const CompiledModel>& compiled_model);
|
||||
SyncInferRequest(const SyncInferRequest &) = delete;
|
||||
~SyncInferRequest() override = default;
|
||||
|
||||
void infer() override;
|
||||
std::vector<ov::ProfilingInfo> get_profiling_info() const override;
|
||||
std::vector<ov::SoPtr<ov::IVariableState>> query_state() const override;
|
||||
|
||||
void set_tensor(const ov::Output<const ov::Node>& port, const ov::SoPtr<ov::ITensor>& tensor) override;
|
||||
void set_tensors_impl(const ov::Output<const ov::Node> port, const std::vector<ov::SoPtr<ov::ITensor>>& tensors) override;
|
||||
|
||||
ov::SoPtr<ov::ITensor> get_tensor(const ov::Output<const ov::Node>& port) const override;
|
||||
|
||||
void set_task_executor(const std::shared_ptr<ov::threading::ITaskExecutor>& task_executor);
|
||||
void setup_stream_graph();
|
||||
void enqueue_notify();
|
||||
void wait_notify();
|
||||
|
||||
void enqueue();
|
||||
void wait();
|
||||
|
||||
bool use_external_queue() const { return m_use_external_queue; }
|
||||
|
||||
private:
|
||||
void check_tensors() const override;
|
||||
|
||||
std::unordered_map<std::string, TensorWrapper> m_user_inputs;
|
||||
std::unordered_map<std::string, TensorWrapper> m_user_outputs;
|
||||
|
||||
std::unordered_map<std::string, TensorWrapper> m_plugin_inputs;
|
||||
std::unordered_map<std::string, TensorWrapper> m_plugin_outputs;
|
||||
|
||||
std::unordered_map<std::string, ov::Output<const ov::Node>> m_input_ports_map;
|
||||
std::unordered_map<std::string, ov::Output<const ov::Node>> m_output_ports_map;
|
||||
std::unordered_map<std::string, std::string> m_output_names_map;
|
||||
|
||||
std::map<cldnn::primitive_id, cldnn::network_output> m_internal_outputs;
|
||||
|
||||
std::shared_ptr<Graph> m_graph;
|
||||
RemoteContextImpl::Ptr m_context = nullptr;
|
||||
std::shared_ptr<ov::threading::IStreamsExecutor> m_stream_executor = nullptr;
|
||||
bool m_enable_profiling = false;
|
||||
bool m_use_external_queue = false;
|
||||
|
||||
std::vector<cldnn::event::ptr> prepare_input(const std::string& name, const ov::Output<const ov::Node>& port, const TensorWrapper& user_tensor_wrapper);
|
||||
std::vector<cldnn::event::ptr> prepare_output(const std::string& name, const ov::Output<const ov::Node>& port, const TensorWrapper& user_tensor_wrapper);
|
||||
std::vector<cldnn::event::ptr> prepare_batched_input(const std::string& name,
|
||||
const ov::Output<const ov::Node>& port,
|
||||
const std::vector<ov::SoPtr<ov::ITensor>>& user_tensors);
|
||||
|
||||
TensorWrapper create_or_share_device_tensor(const TensorWrapper& user_tensor_wrapper,
|
||||
const std::string& name,
|
||||
const ov::PartialShape& pshape,
|
||||
ov::element::Type element_type,
|
||||
bool need_lockable_mem) const;
|
||||
std::shared_ptr<ov::ITensor> reinterpret_device_tensor(std::shared_ptr<RemoteTensorImpl> tensor, const ov::Shape new_shape) const;
|
||||
std::shared_ptr<ov::ITensor> create_host_tensor(const ov::PartialShape& port_shape, const ov::element::Type& port_element_type) const;
|
||||
std::shared_ptr<ov::ITensor> create_device_tensor(const ov::Shape& pshape, ov::element::Type element_type,
|
||||
bool need_lockable_memory = false, void* mem_ptr = nullptr) const;
|
||||
std::shared_ptr<ov::ITensor> create_shared_device_tensor(const ov::Shape& pshape, ov::element::Type element_type, void* usm_host_mem) const;
|
||||
|
||||
void allocate_inputs();
|
||||
void allocate_outputs();
|
||||
void allocate_states();
|
||||
void allocate_input(const ov::Output<const ov::Node>& port, const std::string& name);
|
||||
void allocate_output(const ov::Output<const ov::Node>& port, const std::string& name);
|
||||
cldnn::event::ptr copy_output_data(cldnn::memory::ptr src, const ov::ITensor& dst) const;
|
||||
|
||||
void init_mappings(bool is_legacy_api);
|
||||
bool is_batched_input(const ov::Output<const ov::Node>& port) const;
|
||||
};
|
||||
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
@@ -3,45 +3,24 @@
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include <cpp_interfaces/interface/ie_ivariable_state_internal.hpp>
|
||||
#include "openvino/runtime/ivariable_state.hpp"
|
||||
#include "intel_gpu/plugin/graph.hpp"
|
||||
#include <functional>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
class VariableState : public InferenceEngine::IVariableStateInternal {
|
||||
class VariableState : public ov::IVariableState {
|
||||
public:
|
||||
VariableState(const std::string& name, const std::vector<cldnn::network::VariableState::Ptr>& states,
|
||||
cldnn::engine& engine, int currentBatch);
|
||||
VariableState(const std::string& name, cldnn::network::VariableState::Ptr states, cldnn::engine& engine);
|
||||
|
||||
/**
|
||||
* @brief Reset internal variable state for relevant infer request, to a value specified as
|
||||
* default for according `ReadValue` node
|
||||
*/
|
||||
void Reset() override;
|
||||
|
||||
/**
|
||||
* @brief Sets the new state for the next inference
|
||||
* @param newState A new state
|
||||
*/
|
||||
void SetState(const InferenceEngine::Blob::Ptr &newState) override;
|
||||
|
||||
/**
|
||||
* @brief Returns the value of the variable state.
|
||||
* @return The value of the variable state
|
||||
*/
|
||||
InferenceEngine::Blob::CPtr GetState() const override;
|
||||
|
||||
protected:
|
||||
InferenceEngine::SizeVector AggregateShape(const cldnn::layout &layout);
|
||||
void IterateOverStates(std::function<void(cldnn::network::VariableState&)> f) const;
|
||||
void reset() override;
|
||||
void set_state(const ov::SoPtr<ov::ITensor>& state) override;
|
||||
const ov::SoPtr<ov::ITensor>& get_state() const override;
|
||||
|
||||
private:
|
||||
int currentBatch_;
|
||||
std::vector<cldnn::network::VariableState::Ptr> states_;
|
||||
InferenceEngine::TensorDesc desc_;
|
||||
cldnn::engine& engine_;
|
||||
cldnn::network::VariableState::Ptr m_variable_state;
|
||||
cldnn::engine& m_engine;
|
||||
};
|
||||
|
||||
} // namespace intel_gpu
|
||||
|
||||
@@ -36,24 +36,20 @@ struct convert_color : public primitive_base<convert_color> {
|
||||
/// @param input_color_format Color to convert from.
|
||||
/// @param output_color_format Color to convert to.
|
||||
/// @param mem_type Memory type.
|
||||
/// @param output_layout Requested memory layout.
|
||||
convert_color(const primitive_id& id,
|
||||
const std::vector<input_info>& inputs,
|
||||
const color_format input_color_format,
|
||||
const color_format output_color_format,
|
||||
const memory_type mem_type,
|
||||
const layout& output_layout,
|
||||
const padding& output_padding = padding())
|
||||
: primitive_base(id, inputs, {output_padding}),
|
||||
input_color_format(input_color_format),
|
||||
output_color_format(output_color_format),
|
||||
mem_type(mem_type),
|
||||
output_layout(output_layout) {}
|
||||
mem_type(mem_type) {}
|
||||
|
||||
color_format input_color_format = color_format::RGB;
|
||||
color_format output_color_format = color_format::RGB;
|
||||
memory_type mem_type = memory_type::buffer;
|
||||
layout output_layout;
|
||||
|
||||
size_t hash() const override {
|
||||
size_t seed = primitive::hash();
|
||||
@@ -71,8 +67,7 @@ struct convert_color : public primitive_base<convert_color> {
|
||||
|
||||
return input_color_format == rhs_casted.input_color_format &&
|
||||
output_color_format == rhs_casted.output_color_format &&
|
||||
mem_type == rhs_casted.mem_type &&
|
||||
output_layout == rhs_casted.output_layout;
|
||||
mem_type == rhs_casted.mem_type;
|
||||
}
|
||||
|
||||
void save(BinaryOutputBuffer& ob) const override {
|
||||
@@ -80,7 +75,6 @@ struct convert_color : public primitive_base<convert_color> {
|
||||
ob << make_data(&input_color_format, sizeof(color_format));
|
||||
ob << make_data(&output_color_format, sizeof(color_format));
|
||||
ob << make_data(&mem_type, sizeof(memory_type));
|
||||
ob << output_layout;
|
||||
}
|
||||
|
||||
void load(BinaryInputBuffer& ib) override {
|
||||
@@ -88,7 +82,6 @@ struct convert_color : public primitive_base<convert_color> {
|
||||
ib >> make_data(&input_color_format, sizeof(color_format));
|
||||
ib >> make_data(&output_color_format, sizeof(color_format));
|
||||
ib >> make_data(&mem_type, sizeof(memory_type));
|
||||
ib >> output_layout;
|
||||
}
|
||||
};
|
||||
} // namespace cldnn
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (C) 2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "openvino/util/file_util.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
// Version of save_binary that don't trow an exception if attempt to open file fails
|
||||
void save_binary(const std::string& path, std::vector<uint8_t> binary);
|
||||
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
@@ -235,7 +235,7 @@ inline data_types element_type_to_data_type(ov::element::Type t) {
|
||||
case ov::element::Type_t::i64:
|
||||
return cldnn::data_types::i64;
|
||||
case ov::element::Type_t::boolean:
|
||||
return cldnn::data_types::i8;
|
||||
return cldnn::data_types::u8;
|
||||
case ov::element::Type_t::u1:
|
||||
return cldnn::data_types::bin;
|
||||
default:
|
||||
|
||||
@@ -11,9 +11,30 @@
|
||||
namespace cldnn {
|
||||
GPU_DEFINE_PRIMITIVE_TYPE_ID(convert_color)
|
||||
|
||||
layout convert_color_inst::calc_output_layout(convert_color_node const& node, kernel_impl_params const& impl_param) {
|
||||
layout convert_color_inst::calc_output_layout(convert_color_node const& /* node */, kernel_impl_params const& impl_param) {
|
||||
auto desc = impl_param.typed_desc<convert_color>();
|
||||
return desc->output_layout;
|
||||
|
||||
auto src_fmt = desc->input_color_format;
|
||||
auto dst_fmt = desc->output_color_format;
|
||||
auto dst_is_rgb_or_bgr = dst_fmt == convert_color::color_format::BGR ||
|
||||
dst_fmt == convert_color::color_format::RGB;
|
||||
auto inputs_count = desc->input_size();
|
||||
bool single_plane_input = inputs_count == 1;
|
||||
const size_t h_dim = 1;
|
||||
const size_t c_dim = 3;
|
||||
if ((src_fmt == convert_color::color_format::NV12 || src_fmt == convert_color::color_format::I420) && dst_is_rgb_or_bgr) {
|
||||
auto out_layout = impl_param.get_input_layout(0);
|
||||
out_layout.format = format::bfyx;
|
||||
auto out_shape = out_layout.get_partial_shape();
|
||||
out_shape[c_dim] = 3;
|
||||
if (single_plane_input) {
|
||||
out_shape[h_dim] = out_shape[h_dim] * 2 / 3;
|
||||
}
|
||||
out_layout.set_partial_shape(out_shape);
|
||||
|
||||
return out_layout;
|
||||
}
|
||||
OPENVINO_THROW("[GPU] Unsupported color format combinations");
|
||||
}
|
||||
|
||||
std::string convert_color_inst::to_string(convert_color_node const& node) {
|
||||
|
||||
@@ -122,7 +122,7 @@ std::vector<layout> crop_inst::calc_output_layouts(const crop_node& /*node*/, co
|
||||
// update split offsets
|
||||
if (is_output_static) {
|
||||
auto p_param = const_cast<kernel_impl_params*>(&impl_param);
|
||||
InferenceEngine::SizeVector startOffset(p_param->input_layouts[0].get_partial_shape().size());
|
||||
ov::Shape startOffset(p_param->input_layouts[0].get_partial_shape().size());
|
||||
auto input_shape = p_param->input_layouts[0].get_partial_shape();
|
||||
auto dims = p_param->input_layouts[0].get_partial_shape().size();
|
||||
for (int32_t prev = 0; prev < desc->output_idx; prev++) {
|
||||
|
||||
@@ -54,9 +54,9 @@ attach_convert_color_impl::attach_convert_color_impl() {
|
||||
std::make_tuple(data_types::f32, format::nv12),
|
||||
std::make_tuple(data_types::f16, format::nv12),
|
||||
std::make_tuple(data_types::u8, format::nv12),
|
||||
std::make_tuple(data_types::f32, format::byxf),
|
||||
std::make_tuple(data_types::f16, format::byxf),
|
||||
std::make_tuple(data_types::u8, format::byxf),
|
||||
std::make_tuple(data_types::f32, format::bfyx),
|
||||
std::make_tuple(data_types::f16, format::bfyx),
|
||||
std::make_tuple(data_types::u8, format::bfyx),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
#include "intel_gpu/graph/serialization/binary_buffer.hpp"
|
||||
#include "intel_gpu/plugin/common_utils.hpp"
|
||||
#include "intel_gpu/runtime/memory.hpp"
|
||||
#include "intel_gpu/runtime/file_util.hpp"
|
||||
#include "to_string_utils.h"
|
||||
#include "register.hpp"
|
||||
#include "utils.hpp"
|
||||
#include "openvino/util/file_util.hpp"
|
||||
#include "runtime/ocl/ocl_event.hpp"
|
||||
|
||||
#include "quantize_inst.h"
|
||||
@@ -368,7 +368,7 @@ private:
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(cacheAccessMutex);
|
||||
ov::util::save_binary(generate_cache_path_from_key(config, key), cache);
|
||||
ov::intel_gpu::save_binary(generate_cache_path_from_key(config, key), cache);
|
||||
}
|
||||
} else {
|
||||
_prim = PrimType(_pd, cache);
|
||||
|
||||
@@ -768,8 +768,7 @@ event::ptr network::set_input_data(const primitive_id& id, memory::ptr data) {
|
||||
|
||||
primitive_inst = find_primitive(id);
|
||||
|
||||
if (primitive_inst == nullptr)
|
||||
throw std::runtime_error("topology doesn't contain primitive:" + id);
|
||||
OPENVINO_ASSERT(primitive_inst != nullptr, "[GPU] topology doesn't contain primitive: ", id);
|
||||
|
||||
if (primitive_inst->type() != input_layout::type_id()) {
|
||||
CLDNN_ERROR_MESSAGE(id, "primitive " + id + " is not an input");
|
||||
@@ -911,8 +910,7 @@ std::vector<event::ptr> network::set_output_memory(const primitive_id& id, memor
|
||||
std::vector<event::ptr> ret_ev;
|
||||
p_inst = find_primitive(id);
|
||||
|
||||
if (!p_inst)
|
||||
throw std::runtime_error("topology doesn't contain primitive: " + id);
|
||||
OPENVINO_ASSERT(p_inst != nullptr, "[GPU] topology doesn't contain primitive: ", id);
|
||||
|
||||
auto iter = std::find(_outputs.begin(), _outputs.end(), p_inst);
|
||||
if (iter == _outputs.end())
|
||||
@@ -927,7 +925,11 @@ std::vector<event::ptr> network::set_output_memory(const primitive_id& id, memor
|
||||
}
|
||||
|
||||
for (auto& prim : o_iter->second) {
|
||||
ret_ev.push_back(prim->set_output_memory(eng.reinterpret_buffer(*mem_new, prim->output_memory().get_layout()), false));
|
||||
auto mem = mem_new;
|
||||
if (!prim->is_dynamic() && mem_new && prim->output_memory_ptr())
|
||||
mem = eng.reinterpret_buffer(*mem_new, prim->output_memory().get_layout());
|
||||
|
||||
ret_ev.push_back(prim->set_output_memory(mem));
|
||||
if (!_reset_arguments &&
|
||||
(prim->type() != cldnn::data::type_id() && !(prim->type() == cldnn::mutable_data::type_id() && prim->dependencies().empty()))) {
|
||||
prim->set_arguments();
|
||||
@@ -1722,6 +1724,10 @@ void network::allocate_variables_memories() {
|
||||
}
|
||||
}
|
||||
|
||||
const cldnn::network::variables_state_info_map& network::get_variables_state_info() const {
|
||||
return _variables_state_info;
|
||||
}
|
||||
|
||||
void network::set_variables_state_info(const std::string& variable_id, const cldnn::layout& layout) {
|
||||
auto it = _variables_state_info.find(variable_id);
|
||||
if (it == _variables_state_info.end()) {
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/runtime/system_conf.hpp"
|
||||
|
||||
#include "intel_gpu/runtime/memory.hpp"
|
||||
#include "intel_gpu/runtime/engine.hpp"
|
||||
#include "intel_gpu/runtime/debug_configuration.hpp"
|
||||
#include "intel_gpu/runtime/itt.hpp"
|
||||
#include "intel_gpu/graph/program.hpp"
|
||||
|
||||
#include <ie_system_conf.h>
|
||||
|
||||
#include "auto_tuner.h"
|
||||
#include "layout_optimizer.h"
|
||||
#include "pass_manager.h"
|
||||
@@ -105,12 +105,12 @@ using namespace cldnn;
|
||||
using namespace ov::intel_gpu;
|
||||
|
||||
static void adjust_num_cores(ov::threading::IStreamsExecutor::Config& config) {
|
||||
if (InferenceEngine::getAvailableCoresTypes().size() == 1) {
|
||||
if (ov::get_available_cores_types().size() == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto total_num_cores = InferenceEngine::getNumberOfLogicalCPUCores();
|
||||
const auto total_num_big_cores = InferenceEngine::getNumberOfLogicalCPUCores(true);
|
||||
const auto total_num_cores = ov::get_number_of_logical_cpu_cores();
|
||||
const auto total_num_big_cores = ov::get_number_of_logical_cpu_cores(true);
|
||||
const auto total_num_little_cores = total_num_cores - total_num_big_cores;
|
||||
auto core_type = config._threadPreferredCoreType;
|
||||
|
||||
|
||||
@@ -117,7 +117,11 @@ std::unique_ptr<json_composite> program_node::desc_to_json() const {
|
||||
s << get_preferred_impl_type();
|
||||
node_info->add("preferred impl", s.str());
|
||||
|
||||
node_info->add("output layout", output_layouts[0].to_short_string());
|
||||
json_composite output_layouts_desc;
|
||||
for (size_t i = 0; i < output_layouts.size(); i++) {
|
||||
output_layouts_desc.add(std::to_string(i), output_layouts[i].to_short_string());
|
||||
}
|
||||
node_info->add("output layouts", output_layouts_desc);
|
||||
|
||||
node_info->add("constant", bool_to_str(constant));
|
||||
node_info->add("in data flow", bool_to_str(data_flow));
|
||||
@@ -168,7 +172,9 @@ std::unique_ptr<json_composite> program_node::desc_to_json() const {
|
||||
if (empty) {
|
||||
empty = false;
|
||||
}
|
||||
deps_ptrs.push_back(std::to_string(reinterpret_cast<uintptr_t>(itr->first)));
|
||||
auto ptr = std::to_string(reinterpret_cast<uintptr_t>(itr->first));
|
||||
auto port = std::to_string(itr->second);
|
||||
deps_ptrs.push_back(ptr + "(" + port + ")");
|
||||
itr++;
|
||||
}
|
||||
if (deps_ptrs.empty()) {
|
||||
|
||||
@@ -28,10 +28,16 @@ layout reorder_inst::calc_output_layout(reorder_node const& node, kernel_impl_pa
|
||||
}
|
||||
|
||||
if (ifmt.is_nv12() && !desc->has_surface_input()) {
|
||||
auto data_size = tensor{ input_layout.batch(), input_layout.feature() * 3,
|
||||
input_layout.spatial(0), input_layout.spatial(1) };
|
||||
const size_t h_dim = 1;
|
||||
const size_t c_dim = 3;
|
||||
|
||||
auto out_shape = input_layout.get_partial_shape();
|
||||
out_shape[c_dim] = 3;
|
||||
if (desc->input_size() == 1)
|
||||
out_shape[h_dim] = out_shape[h_dim] * 2 / 3;
|
||||
|
||||
if (ofmt != ifmt)
|
||||
return layout(odt, ofmt, data_size, op);
|
||||
return layout(out_shape, odt, ofmt, op);
|
||||
|
||||
CLDNN_ERROR_MESSAGE(desc->id, "No image_nv12 to image_nv12 reorder is supported");
|
||||
} else if (ofmt.is_winograd() && ifmt.is_winograd()) {
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "ngraph/op/unique.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
|
||||
#include "include/batch_headers/fetch_data.cl"
|
||||
|
||||
|
||||
#define IMAGE_W INPUT0_SIZE_Y
|
||||
#define IMAGE_H (INPUT0_FEATURE_NUM * 2 / 3)
|
||||
|
||||
#if defined(CONVERT_FROM_NV12) || defined(CONVERT_FROM_I420)
|
||||
#ifdef BUFFER_MEM
|
||||
KERNEL(convert_color_ref)(const __global INPUT0_TYPE* input1,
|
||||
@@ -19,22 +23,22 @@ KERNEL(convert_color_ref)(const __global INPUT0_TYPE* input1,
|
||||
const uint y = get_global_id(1);
|
||||
const uint x = get_global_id(2);
|
||||
|
||||
float Y = input1[GET_DATA_INDEX(INPUT0, b, 0, y, x)];
|
||||
float Y = input1[GET_DATA_INDEX(INPUT0, b, y, x, 0)];
|
||||
|
||||
#if INPUTS_COUNT == 3
|
||||
float U = input2[GET_DATA_INDEX(INPUT1, b, 0, y / 2, x / 2)];
|
||||
float V = input3[GET_DATA_INDEX(INPUT2, b, 0, y / 2, x / 2)];
|
||||
float U = input2[GET_DATA_INDEX(INPUT1, b, y / 2, x / 2, 0)];
|
||||
float V = input3[GET_DATA_INDEX(INPUT2, b, y / 2, x / 2, 0)];
|
||||
#elif INPUTS_COUNT == 2
|
||||
float U = input2[GET_DATA_INDEX(INPUT1, b, 0, y / 2, x / 2)];
|
||||
float V = input2[GET_DATA_INDEX(INPUT1, b, 1, y / 2, x / 2)];
|
||||
float U = input2[GET_DATA_INDEX(INPUT1, b, y / 2, x / 2, 0)];
|
||||
float V = input2[GET_DATA_INDEX(INPUT1, b, y / 2, x / 2, 1)];
|
||||
#else // Single plane
|
||||
uint input_uv_offset = INPUT0_SIZE_X * INPUT0_SIZE_Y / 3 * 2;
|
||||
uint input_uv_offset = IMAGE_W * IMAGE_H;
|
||||
#ifdef CONVERT_FROM_NV12
|
||||
float U = input1[GET_DATA_INDEX(INPUT0, b, 0, y / 2, (x / 2) * 2) + input_uv_offset];
|
||||
float V = input1[GET_DATA_INDEX(INPUT0, b, 1, y / 2, (x / 2) * 2) + input_uv_offset];
|
||||
float U = input1[GET_DATA_INDEX(INPUT0, b, (y / 2), (x / 2) * 2, 0) + input_uv_offset];
|
||||
float V = input1[GET_DATA_INDEX(INPUT0, b, (y / 2), (x / 2) * 2, 0) + input_uv_offset + 1];
|
||||
#else
|
||||
float U = input1[GET_DATA_INDEX(INPUT0, b, 0, 0, x / 2 + (y / 2)*(INPUT0_Y_PITCH / 2)) + input_uv_offset];
|
||||
float V = input1[GET_DATA_INDEX(INPUT0, b, 0, 0, x / 2 + (y / 2)*(INPUT0_Y_PITCH / 2)) + 5 * input_uv_offset / 4];
|
||||
float U = input1[GET_DATA_INDEX(INPUT0, b, 0, x / 2 + (y / 2)*(INPUT0_FEATURE_PITCH / 2), 0) + input_uv_offset];
|
||||
float V = input1[GET_DATA_INDEX(INPUT0, b, 0, x / 2 + (y / 2)*(INPUT0_FEATURE_PITCH / 2), 0) + 5 * input_uv_offset / 4];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -53,13 +57,13 @@ KERNEL(convert_color_ref)(const __global INPUT0_TYPE* input1,
|
||||
#endif
|
||||
|
||||
#ifdef CONVERT_TO_RGB
|
||||
output[OUTPUT_GET_INDEX(b, 0, y, x)] = ACTIVATION(TO_OUTPUT_TYPE(R), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, 1, y, x)] = ACTIVATION(TO_OUTPUT_TYPE(G), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, 2, y, x)] = ACTIVATION(TO_OUTPUT_TYPE(B), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, y, x, 0)] = ACTIVATION(TO_OUTPUT_TYPE(R), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, y, x, 1)] = ACTIVATION(TO_OUTPUT_TYPE(G), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, y, x, 2)] = ACTIVATION(TO_OUTPUT_TYPE(B), ACTIVATION_PARAMS);
|
||||
#else // BGR
|
||||
output[OUTPUT_GET_INDEX(b, 0, y, x)] = ACTIVATION(TO_OUTPUT_TYPE(B), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, 1, y, x)] = ACTIVATION(TO_OUTPUT_TYPE(G), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, 2, y, x)] = ACTIVATION(TO_OUTPUT_TYPE(R), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, y, x, 0)] = ACTIVATION(TO_OUTPUT_TYPE(B), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, y, x, 1)] = ACTIVATION(TO_OUTPUT_TYPE(G), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, y, x, 2)] = ACTIVATION(TO_OUTPUT_TYPE(R), ACTIVATION_PARAMS);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -92,9 +96,8 @@ KERNEL(convert_color_ref)(read_only image2d_t input1,
|
||||
float Ucomponent = mad(UV.x, 255.0f, -128.f);
|
||||
float Vcomponent = mad(UV.y, 255.0f, -128.f);
|
||||
#else // Single plane
|
||||
uint input_y_offset = INPUT0_SIZE_Y / 3 * 2;
|
||||
float4 U = read_imagef(input1, (int2)((x / 2) * 2, y / 2 + input_y_offset));
|
||||
float4 V = read_imagef(input1, (int2)((x / 2) * 2 + 1, y / 2 + input_y_offset));
|
||||
float4 U = read_imagef(input1, (int2)((x / 2) * 2, y / 2 + IMAGE_H));
|
||||
float4 V = read_imagef(input1, (int2)((x / 2) * 2 + 1, y / 2 + IMAGE_H));
|
||||
float Ucomponent = mad(U.x, 255.0f, -128.f);
|
||||
float Vcomponent = mad(V.x, 255.0f, -128.f);
|
||||
#endif
|
||||
@@ -110,13 +113,13 @@ KERNEL(convert_color_ref)(read_only image2d_t input1,
|
||||
#endif
|
||||
|
||||
#ifdef CONVERT_TO_RGB
|
||||
output[OUTPUT_GET_INDEX(b, 0, y, x)] = ACTIVATION(TO_OUTPUT_TYPE(R), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, 1, y, x)] = ACTIVATION(TO_OUTPUT_TYPE(G), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, 2, y, x)] = ACTIVATION(TO_OUTPUT_TYPE(B), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, y, x, 0)] = ACTIVATION(TO_OUTPUT_TYPE(R), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, y, x, 1)] = ACTIVATION(TO_OUTPUT_TYPE(G), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, y, x, 2)] = ACTIVATION(TO_OUTPUT_TYPE(B), ACTIVATION_PARAMS);
|
||||
#else // BGR
|
||||
output[OUTPUT_GET_INDEX(b, 0, y, x)] = ACTIVATION(TO_OUTPUT_TYPE(B), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, 1, y, x)] = ACTIVATION(TO_OUTPUT_TYPE(G), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, 2, y, x)] = ACTIVATION(TO_OUTPUT_TYPE(R), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, y, x, 0)] = ACTIVATION(TO_OUTPUT_TYPE(B), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, y, x, 1)] = ACTIVATION(TO_OUTPUT_TYPE(G), ACTIVATION_PARAMS);
|
||||
output[OUTPUT_GET_INDEX(b, y, x, 2)] = ACTIVATION(TO_OUTPUT_TYPE(R), ACTIVATION_PARAMS);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -86,7 +86,7 @@ KERNEL (reorder_data)(
|
||||
|
||||
#if defined INPUT0_LAYOUT_NV12 && !SURFACE_INPUT
|
||||
const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_FILTER_NEAREST | CLK_ADDRESS_CLAMP;
|
||||
float4 colorVYU = read_imagef(input, sampler, (int2)(x, y));
|
||||
float4 colorVYU = read_imagef(input, sampler, (int2)(y, f));
|
||||
|
||||
float Ycomponent = mad(colorVYU.s1, 296.82f, -18.624f);
|
||||
float Ucomponent = mad(colorVYU.s2, 255.0f, -128.f);
|
||||
@@ -128,7 +128,7 @@ KERNEL (reorder_data)(
|
||||
res = MEAN_OP(res, mean_subtract[GET_DATA_INDEX_SAFE(MEAN_SUBTRACT, msv.s0, msv.s1, /*msv.s2, msv.s3, msv.s4,msv.s5,*/ msv.s6, msv.s7)]);
|
||||
#endif
|
||||
#elif SURFACE_INPUT
|
||||
float4 Y = read_imagef(input, (int2)(x, y));
|
||||
float4 Y = read_imagef(input, (int2)(y, f));
|
||||
float Ycomponent = mad(Y.x, 296.82f, -18.624f);
|
||||
float res = clamp(Ycomponent, 0.f, 255.f);
|
||||
#else
|
||||
|
||||
@@ -156,6 +156,7 @@ std::string toString(WeightsType wType) {
|
||||
case WeightsType::F16: return "F16";
|
||||
case WeightsType::F32: return "F32";
|
||||
case WeightsType::INT8: return "INT8";
|
||||
case WeightsType::UINT8: return "UINT8";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ CommonDispatchData ConvertColorKernelBase::SetDefault(const convert_color_params
|
||||
auto in_layout = params.inputs[0].GetLayout();
|
||||
auto out_layout = params.outputs[0].GetLayout();
|
||||
|
||||
dispatchData.gws = { out.Batch().v, out.Y().v, out.X().v };
|
||||
dispatchData.gws = { out.Batch().v, out.Feature().v, out.Y().v };
|
||||
dispatchData.lws = GetOptimalLocalWorkGroupSizes(dispatchData.gws, params.engineInfo, in_layout, out_layout);
|
||||
|
||||
return dispatchData;
|
||||
|
||||
+2
-2
@@ -19,8 +19,8 @@ ParamsKey ConvertColorKernelRef::GetSupportedKey() const {
|
||||
k.EnableOutputDataType(Datatype::UINT8);
|
||||
|
||||
k.EnableInputLayout(DataLayout::nv12);
|
||||
k.EnableInputLayout(DataLayout::byxf);
|
||||
k.EnableOutputLayout(DataLayout::byxf);
|
||||
k.EnableInputLayout(DataLayout::bfyx);
|
||||
k.EnableOutputLayout(DataLayout::bfyx);
|
||||
|
||||
k.EnableDifferentTypes();
|
||||
k.EnableTensorOffset();
|
||||
|
||||
@@ -9,40 +9,33 @@
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
AsyncInferRequest::AsyncInferRequest(const InferRequest::Ptr &inferRequest,
|
||||
const InferenceEngine::ITaskExecutor::Ptr& taskExecutor,
|
||||
const InferenceEngine::ITaskExecutor::Ptr& waitExecutor,
|
||||
const InferenceEngine::ITaskExecutor::Ptr& callbackExecutor)
|
||||
: AsyncInferRequestThreadSafeDefault(inferRequest, taskExecutor, callbackExecutor), _inferRequest(inferRequest), _waitExecutor(waitExecutor) {
|
||||
_pipeline = {};
|
||||
|
||||
if (!_inferRequest->use_external_queue()) {
|
||||
_pipeline.push_back({taskExecutor,
|
||||
[this] {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "AsyncInferRequest::PreprocessingAndStartPipeline");
|
||||
_inferRequest->setup_stream_graph();
|
||||
_inferRequest->enqueue();
|
||||
_inferRequest->wait();
|
||||
} });
|
||||
} else {
|
||||
_pipeline.push_back({ _waitExecutor,
|
||||
AsyncInferRequest::AsyncInferRequest(const std::shared_ptr<SyncInferRequest>& infer_request,
|
||||
const std::shared_ptr<ov::threading::ITaskExecutor>& task_executor,
|
||||
const std::shared_ptr<ov::threading::ITaskExecutor>& wait_executor,
|
||||
const std::shared_ptr<ov::threading::ITaskExecutor>& callback_executor)
|
||||
: ov::IAsyncInferRequest(infer_request, task_executor, callback_executor)
|
||||
, m_infer_request(infer_request)
|
||||
, m_wait_executor(wait_executor) {
|
||||
m_infer_request->set_task_executor(task_executor);
|
||||
if (infer_request->use_external_queue()) {
|
||||
m_pipeline.clear();
|
||||
m_pipeline.emplace_back(wait_executor,
|
||||
[this] {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "AsyncInferRequest::WaitPipeline");
|
||||
_inferRequest->wait_notify();
|
||||
} });
|
||||
m_infer_request->wait_notify();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncInferRequest::StartAsync_ThreadUnsafe() {
|
||||
if (_inferRequest->use_external_queue()) {
|
||||
_inferRequest->setup_stream_graph();
|
||||
_inferRequest->enqueue_notify();
|
||||
void AsyncInferRequest::start_async() {
|
||||
if (m_infer_request->use_external_queue()) {
|
||||
m_infer_request->setup_stream_graph();
|
||||
m_infer_request->enqueue_notify();
|
||||
}
|
||||
Parent::StartAsync_ThreadUnsafe();
|
||||
Parent::start_async();
|
||||
}
|
||||
|
||||
AsyncInferRequest::~AsyncInferRequest() {
|
||||
StopAndWait();
|
||||
stop_and_wait();
|
||||
}
|
||||
|
||||
} // namespace intel_gpu
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "intel_gpu/plugin/async_infer_request_legacy.hpp"
|
||||
#include "intel_gpu/runtime/itt.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
AsyncInferRequestLegacy::AsyncInferRequestLegacy(const InferRequestLegacy::Ptr &inferRequest,
|
||||
const InferenceEngine::ITaskExecutor::Ptr& taskExecutor,
|
||||
const InferenceEngine::ITaskExecutor::Ptr& waitExecutor,
|
||||
const InferenceEngine::ITaskExecutor::Ptr& callbackExecutor)
|
||||
: AsyncInferRequestThreadSafeDefault(inferRequest, taskExecutor, callbackExecutor), _inferRequest(inferRequest), _waitExecutor(waitExecutor) {
|
||||
_pipeline = {};
|
||||
|
||||
if (!_inferRequest->use_external_queue()) {
|
||||
_pipeline.push_back({taskExecutor,
|
||||
[this] {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "AsyncInferRequest::PreprocessingAndStartPipeline");
|
||||
_inferRequest->setup_stream_graph();
|
||||
_inferRequest->preprocess();
|
||||
_inferRequest->enqueue();
|
||||
_inferRequest->wait();
|
||||
} });
|
||||
} else {
|
||||
_pipeline.push_back({ _waitExecutor,
|
||||
[this] {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "AsyncInferRequest::WaitPipeline");
|
||||
_inferRequest->wait_notify();
|
||||
} });
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncInferRequestLegacy::StartAsync_ThreadUnsafe() {
|
||||
if (_inferRequest->use_external_queue()) {
|
||||
_inferRequest->setup_stream_graph();
|
||||
_inferRequest->preprocess_notify();
|
||||
_inferRequest->enqueue_notify();
|
||||
}
|
||||
Parent::StartAsync_ThreadUnsafe();
|
||||
}
|
||||
|
||||
AsyncInferRequestLegacy::~AsyncInferRequestLegacy() {
|
||||
StopAndWait();
|
||||
}
|
||||
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
@@ -3,27 +3,22 @@
|
||||
//
|
||||
|
||||
#include "intel_gpu/plugin/legacy_api_helper.hpp"
|
||||
#include "intel_gpu/plugin/legacy_remote_context.hpp"
|
||||
|
||||
#include "openvino/pass/serialize.hpp"
|
||||
#include "openvino/runtime/iplugin.hpp"
|
||||
#include "openvino/runtime/intel_gpu/properties.hpp"
|
||||
#include "openvino/util/common_util.hpp"
|
||||
|
||||
#include "intel_gpu/graph/serialization/binary_buffer.hpp"
|
||||
#include "intel_gpu/graph/serialization/layout_serializer.hpp"
|
||||
#include "intel_gpu/graph/serialization/string_serializer.hpp"
|
||||
#include "intel_gpu/graph/serialization/utils.hpp"
|
||||
#include "intel_gpu/graph/serialization/vector_serializer.hpp"
|
||||
#include "intel_gpu/plugin/graph.hpp"
|
||||
#include "intel_gpu/runtime/itt.hpp"
|
||||
#include "intel_gpu/plugin/infer_request.hpp"
|
||||
#include "intel_gpu/plugin/graph.hpp"
|
||||
#include "intel_gpu/plugin/compiled_model.hpp"
|
||||
#include "intel_gpu/plugin/async_infer_request.hpp"
|
||||
#include "intel_gpu/plugin/async_infer_request_legacy.hpp"
|
||||
|
||||
#include <threading/ie_executor_manager.hpp>
|
||||
#include "threading/ie_cpu_streams_executor.hpp"
|
||||
#include "cpp_interfaces/interface/ie_internal_plugin_config.hpp"
|
||||
#include "cpp_interfaces/interface/ie_iinfer_request_internal.hpp"
|
||||
#include "ie_icore.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <utility>
|
||||
@@ -32,214 +27,175 @@
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
#include <openvino/util/common_util.hpp>
|
||||
|
||||
using namespace InferenceEngine;
|
||||
using namespace InferenceEngine::details;
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
CompiledModel::CompiledModel(InferenceEngine::CNNNetwork &network,
|
||||
InferenceEngine::RemoteContext::Ptr context,
|
||||
const ExecutionConfig& config,
|
||||
InferenceEngine::InputsDataMap* inputs,
|
||||
InferenceEngine::OutputsDataMap* outputs) :
|
||||
InferenceEngine::ExecutableNetworkThreadSafeDefault{[&]() -> InferenceEngine::ITaskExecutor::Ptr {
|
||||
if (config.get_property(ov::internal::exclusive_async_requests)) {
|
||||
//exclusiveAsyncRequests essentially disables the streams (and hence should be checked first) => aligned with the CPU behavior
|
||||
return executorManager()->getExecutor("GPU");
|
||||
} else if (config.get_property(ov::num_streams) > 1) {
|
||||
return std::make_shared<InferenceEngine::CPUStreamsExecutor>(
|
||||
IStreamsExecutor::Config{"Intel GPU plugin executor", config.get_property(ov::num_streams)});
|
||||
} else {
|
||||
return std::make_shared<InferenceEngine::CPUStreamsExecutor>(
|
||||
IStreamsExecutor::Config{"Intel GPU plugin executor", 1});
|
||||
}
|
||||
}()},
|
||||
m_context(context),
|
||||
m_config(config),
|
||||
m_taskExecutor{ _taskExecutor },
|
||||
m_waitExecutor(executorManager()->getIdleCPUStreamsExecutor({ "GPUWaitExecutor" })),
|
||||
m_network(network) {
|
||||
auto graph_base = std::make_shared<Graph>(network, get_context_impl(m_context), m_config, 0, inputs, outputs);
|
||||
namespace {
|
||||
std::shared_ptr<ov::threading::ITaskExecutor> create_task_executor(const std::shared_ptr<const ov::IPlugin>& plugin, const ExecutionConfig& config) {
|
||||
if (config.get_property(ov::internal::exclusive_async_requests)) {
|
||||
//exclusive_async_requests essentially disables the streams (and hence should be checked first) => aligned with the CPU behavior
|
||||
return plugin->get_executor_manager()->get_executor("GPU");
|
||||
} else {
|
||||
return std::make_shared<ov::threading::CPUStreamsExecutor>(
|
||||
ov::threading::IStreamsExecutor::Config{"Intel GPU plugin executor", config.get_property(ov::num_streams)});
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
CompiledModel::CompiledModel(std::shared_ptr<ov::Model> model,
|
||||
const std::shared_ptr<const ov::IPlugin>& plugin,
|
||||
RemoteContextImpl::Ptr context,
|
||||
const ExecutionConfig& config)
|
||||
: ov::ICompiledModel(model,
|
||||
plugin,
|
||||
wrap_if_old_api(context, plugin->is_new_api()),
|
||||
create_task_executor(plugin, config))
|
||||
, m_context(context)
|
||||
, m_config(config)
|
||||
, m_wait_executor(std::make_shared<ov::threading::CPUStreamsExecutor>(ov::threading::IStreamsExecutor::Config{"Intel GPU plugin wait executor"}))
|
||||
, m_model(model->is_dynamic() ? model : nullptr)
|
||||
, m_model_name(model->get_friendly_name())
|
||||
, m_inputs(ov::ICompiledModel::inputs())
|
||||
, m_outputs(ov::ICompiledModel::outputs())
|
||||
, m_loaded_from_cache(false) {
|
||||
auto graph_base = std::make_shared<Graph>(model, m_context, m_config, 0);
|
||||
for (uint16_t n = 0; n < m_config.get_property(ov::num_streams); n++) {
|
||||
auto graph = n == 0 ? graph_base : std::make_shared<Graph>(graph_base, n);
|
||||
m_graphs.push_back(graph);
|
||||
}
|
||||
}
|
||||
|
||||
CompiledModel::CompiledModel(cldnn::BinaryInputBuffer& ib,
|
||||
InferenceEngine::RemoteContext::Ptr context,
|
||||
const ExecutionConfig& config,
|
||||
InferenceEngine::InputsDataMap* inputs,
|
||||
InferenceEngine::OutputsDataMap* outputs) :
|
||||
InferenceEngine::ExecutableNetworkThreadSafeDefault{[&]() -> InferenceEngine::ITaskExecutor::Ptr {
|
||||
if (config.get_property(ov::internal::exclusive_async_requests)) {
|
||||
//exclusiveAsyncRequests essentially disables the streams (and hence should be checked first) => aligned with the CPU behavior
|
||||
return executorManager()->getExecutor("GPU");
|
||||
} else if (config.get_property(ov::num_streams) > 1) {
|
||||
return std::make_shared<InferenceEngine::CPUStreamsExecutor>(
|
||||
IStreamsExecutor::Config{"Intel GPU plugin executor", config.get_property(ov::num_streams)});
|
||||
} else {
|
||||
return std::make_shared<InferenceEngine::CPUStreamsExecutor>(
|
||||
IStreamsExecutor::Config{"Intel GPU plugin executor", 1});
|
||||
CompiledModel::CompiledModel(cldnn::BinaryInputBuffer ib,
|
||||
const std::shared_ptr<const ov::IPlugin>& plugin,
|
||||
RemoteContextImpl::Ptr context,
|
||||
const ExecutionConfig& config)
|
||||
: ov::ICompiledModel(nullptr,
|
||||
plugin,
|
||||
wrap_if_old_api(context, plugin->is_new_api()),
|
||||
create_task_executor(plugin, config))
|
||||
, m_context(context)
|
||||
, m_config(config)
|
||||
, m_wait_executor(std::make_shared<ov::threading::CPUStreamsExecutor>(ov::threading::IStreamsExecutor::Config{"Intel GPU plugin wait executor"}))
|
||||
, m_model(nullptr)
|
||||
, m_model_name("")
|
||||
, m_loaded_from_cache(true) {
|
||||
{
|
||||
size_t num_params;
|
||||
ib >> num_params;
|
||||
|
||||
for (size_t idx = 0; idx < num_params; ++idx) {
|
||||
std::string param_name;
|
||||
ib >> param_name;
|
||||
ov::element::Type param_element_type;
|
||||
std::string str_element_type;
|
||||
ib >> str_element_type;
|
||||
std::stringstream oss(str_element_type);
|
||||
oss >> param_element_type;
|
||||
ov::PartialShape param_shape;
|
||||
ib >> param_shape;
|
||||
std::unordered_set<std::string> param_names;
|
||||
size_t num_names;
|
||||
ib >> num_names;
|
||||
for (size_t i = 0; i < num_names; ++i) {
|
||||
std::string name;
|
||||
ib >> name;
|
||||
param_names.emplace(name);
|
||||
}
|
||||
|
||||
auto new_param = std::make_shared<ov::op::v0::Parameter>(param_element_type, param_shape);
|
||||
new_param->set_friendly_name(param_name);
|
||||
new_param->set_element_type(param_element_type);
|
||||
new_param->output(0).get_tensor().set_names(param_names);
|
||||
new_param->validate_and_infer_types();
|
||||
m_inputs.push_back(new_param->output(0));
|
||||
}
|
||||
}()},
|
||||
m_context(context),
|
||||
m_config(config),
|
||||
m_taskExecutor{ _taskExecutor },
|
||||
m_waitExecutor(executorManager()->getIdleCPUStreamsExecutor({ "GPUWaitExecutor" })) {
|
||||
auto context_impl = get_context_impl(m_context);
|
||||
}
|
||||
|
||||
{
|
||||
size_t num_results;
|
||||
ib >> num_results;
|
||||
|
||||
for (size_t idx = 0; idx < num_results; ++idx) {
|
||||
ov::element::Type fake_element_type;
|
||||
std::string str_element_type;
|
||||
ib >> str_element_type;
|
||||
std::stringstream oss(str_element_type);
|
||||
oss >> fake_element_type;
|
||||
|
||||
ov::PartialShape fake_shape;
|
||||
ib >> fake_shape;
|
||||
|
||||
std::string fake_name;
|
||||
ib >> fake_name;
|
||||
|
||||
std::string param_name;
|
||||
ib >> param_name;
|
||||
|
||||
std::unordered_set<std::string> param_names;
|
||||
size_t num_names;
|
||||
ib >> num_names;
|
||||
for (size_t i = 0; i < num_names; ++i) {
|
||||
std::string name;
|
||||
ib >> name;
|
||||
param_names.emplace(name);
|
||||
}
|
||||
|
||||
auto fake_param = std::make_shared<ov::op::v0::Parameter>(fake_element_type, fake_shape);
|
||||
fake_param->set_friendly_name(fake_name);
|
||||
fake_param->validate_and_infer_types();
|
||||
|
||||
auto new_result = std::make_shared<ov::op::v0::Result>(fake_param);
|
||||
new_result->set_friendly_name(param_name);
|
||||
new_result->output(0).get_tensor().set_names(param_names);
|
||||
new_result->validate_and_infer_types();
|
||||
m_outputs.push_back(new_result->output(0));
|
||||
}
|
||||
}
|
||||
|
||||
auto pos = ib.tellg();
|
||||
for (uint16_t n = 0; n < m_config.get_property(ov::num_streams); n++) {
|
||||
ib.seekg(pos);
|
||||
auto graph = std::make_shared<Graph>(ib, context_impl, m_config, n, inputs, outputs);
|
||||
auto graph = std::make_shared<Graph>(ib, context, m_config, 0);
|
||||
m_graphs.push_back(graph);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
IInferRequestInternal::Ptr CompiledModel::GetInferRequestImpl(const std::vector<std::shared_ptr<const ov::Node>>& inputs,
|
||||
const std::vector<std::shared_ptr<const ov::Node>>& outputs) {
|
||||
auto ptr = std::make_shared<T>(inputs, outputs, std::static_pointer_cast<CompiledModel>(shared_from_this()));
|
||||
if (m_config.get_property(ov::num_streams) > 1)
|
||||
ptr->EnableStreams();
|
||||
if (m_config.get_property(ov::enable_profiling))
|
||||
ptr->EnableProfiling();
|
||||
if (m_graphs.front()->use_external_queue())
|
||||
ptr->enable_external_queue();
|
||||
ptr->SetGraph(m_graphs.front());
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
IInferRequestInternal::Ptr CompiledModel::CreateInferRequestImpl(InputsDataMap networkInputs,
|
||||
OutputsDataMap networkOutputs) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "CompiledModel::CreateInferRequestImpl");
|
||||
auto ptr = std::make_shared<InferRequestLegacy>(networkInputs, networkOutputs,
|
||||
std::static_pointer_cast<CompiledModel>(shared_from_this()));
|
||||
if (m_config.get_property(ov::num_streams) > 1)
|
||||
ptr->EnableStreams();
|
||||
if (m_config.get_property(ov::enable_profiling))
|
||||
ptr->EnableProfiling();
|
||||
if (m_graphs.front()->use_external_queue())
|
||||
ptr->enable_external_queue();
|
||||
ptr->SetGraph(m_graphs.front());
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
IInferRequestInternal::Ptr CompiledModel::CreateInferRequestImpl(const std::vector<std::shared_ptr<const ov::Node>>& inputs,
|
||||
const std::vector<std::shared_ptr<const ov::Node>>& outputs) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "CompiledModel::CreateInferRequestImpl");
|
||||
if (m_graphs.front()->GetMaxDynamicBatchSize() > 1)
|
||||
return GetInferRequestImpl<InferRequestLegacy>(inputs, outputs);
|
||||
else
|
||||
return GetInferRequestImpl<InferRequest>(inputs, outputs);
|
||||
}
|
||||
|
||||
IInferRequestInternal::Ptr CompiledModel::CreateInferRequest() {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "CompiledModel::CreateInferRequest");
|
||||
InferenceEngine::IInferRequestInternal::Ptr internalRequest;
|
||||
if (m_graphs.empty()) {
|
||||
OPENVINO_THROW("[GPU] Model not loaded");
|
||||
}
|
||||
|
||||
for (auto& graph : m_graphs) {
|
||||
if (graph == nullptr) {
|
||||
OPENVINO_THROW("[GPU] Model not loaded");
|
||||
}
|
||||
|
||||
if (!graph->IsLoaded()) {
|
||||
OPENVINO_THROW("[GPU] Model not loaded: no networks created");
|
||||
}
|
||||
}
|
||||
|
||||
bool is_legacy = false;
|
||||
if (this->_plugin && _plugin->IsNewAPI()) {
|
||||
internalRequest = CreateInferRequestImpl(_parameters, _results);
|
||||
if (std::dynamic_pointer_cast<InferRequestLegacy>(internalRequest))
|
||||
is_legacy = true;
|
||||
}
|
||||
if (!internalRequest) {
|
||||
internalRequest = CreateInferRequestImpl(_networkInputs, _networkOutputs);
|
||||
is_legacy = true;
|
||||
}
|
||||
internalRequest->setPointerToExecutableNetworkInternal(shared_from_this());
|
||||
if (is_legacy) {
|
||||
return std::make_shared<AsyncInferRequestLegacy>(std::static_pointer_cast<InferRequestLegacy>(internalRequest),
|
||||
m_taskExecutor,
|
||||
m_waitExecutor,
|
||||
_callbackExecutor);
|
||||
}
|
||||
return std::make_shared<AsyncInferRequest>(std::static_pointer_cast<InferRequest>(internalRequest),
|
||||
m_taskExecutor,
|
||||
m_waitExecutor,
|
||||
_callbackExecutor);
|
||||
std::shared_ptr<ov::IAsyncInferRequest> CompiledModel::create_infer_request() const {
|
||||
auto sync_request = create_sync_infer_request();
|
||||
auto async_infer_request = std::make_shared<AsyncInferRequest>(std::static_pointer_cast<SyncInferRequest>(sync_request),
|
||||
get_task_executor(),
|
||||
m_wait_executor,
|
||||
get_callback_executor());
|
||||
return async_infer_request;
|
||||
}
|
||||
|
||||
// Cache blob format:
|
||||
// [ ConstInputsDataMap / ConstOutputsDataMap ]
|
||||
// [ is_dynamic flag ]
|
||||
// [ ov::Node::Input/ ov::Node::Output ]
|
||||
// [ ov::intel_gpu::Graph ]
|
||||
void CompiledModel::Export(std::ostream& networkModel) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "CompiledModel::Export");
|
||||
if (m_graphs.empty())
|
||||
OPENVINO_THROW("[GPU] Model not loaded");
|
||||
void CompiledModel::export_model(std::ostream& model) const {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "CompiledModel::export_model");
|
||||
OPENVINO_ASSERT(!m_graphs.empty(), "[GPU] Model not loaded");
|
||||
|
||||
cldnn::BinaryOutputBuffer ob(networkModel);
|
||||
cldnn::BinaryOutputBuffer ob(model);
|
||||
|
||||
// InputsInfo and OutputsInfo for CNNNetwork
|
||||
{
|
||||
ob << GetInputsInfo().size();
|
||||
|
||||
for (const auto& in : GetInputsInfo()) {
|
||||
ob << in.first;
|
||||
std::string precision(in.second->getPrecision().name());
|
||||
ob << precision;
|
||||
std::stringstream ss;
|
||||
ss << in.second->getInputData()->getLayout();
|
||||
ob << ss.str();
|
||||
ob << in.second->getTensorDesc().getDims();
|
||||
}
|
||||
|
||||
ob << GetOutputsInfo().size();
|
||||
|
||||
for (const auto& out : GetOutputsInfo()) {
|
||||
ob << out.first;
|
||||
std::string precision(out.second->getPrecision().name());
|
||||
ob << precision;
|
||||
std::stringstream ss;
|
||||
ss << out.second->getLayout();
|
||||
ob << ss.str();
|
||||
ob << out.second->getTensorDesc().getDims();
|
||||
}
|
||||
}
|
||||
bool is_dynamic = get_graph(0)->get_network()->is_dynamic();
|
||||
|
||||
ob << is_dynamic;
|
||||
// Inputs
|
||||
{
|
||||
const std::vector<std::shared_ptr<const ov::Node>>& const_params = getInputs();
|
||||
ob << const_params.size();
|
||||
const auto& params = inputs();
|
||||
ob << params.size();
|
||||
|
||||
for (const auto& param : const_params) {
|
||||
auto new_param = ov::as_type_ptr<const ov::op::v0::Parameter>(param);
|
||||
ov::element::Type param_element_type = new_param->get_element_type();
|
||||
|
||||
const std::string& param_name = new_param->get_friendly_name();
|
||||
const ov::PartialShape& param_shape = new_param->get_partial_shape();
|
||||
const ov::Layout& param_layout = new_param->get_layout();
|
||||
const auto& param_names = new_param->output(0).get_tensor().get_names();
|
||||
|
||||
ob << param_name;
|
||||
for (const auto& param : params) {
|
||||
std::stringstream ss;
|
||||
ss << param_element_type;
|
||||
ss << param.get_element_type();
|
||||
|
||||
ob << param.get_node()->get_friendly_name();
|
||||
ob << ss.str();
|
||||
ob << param_shape;
|
||||
ob << param_layout.to_string();
|
||||
ob << param_names.size();
|
||||
for (const auto& name : param_names) {
|
||||
ob << param.get_partial_shape();
|
||||
ob << param.get_names().size();
|
||||
for (const auto& name : param.get_names()) {
|
||||
ob << name;
|
||||
}
|
||||
}
|
||||
@@ -247,66 +203,44 @@ void CompiledModel::Export(std::ostream& networkModel) {
|
||||
|
||||
// Outputs
|
||||
{
|
||||
std::vector<std::shared_ptr<const ov::Node>> const_results = getOutputs();
|
||||
ob << const_results.size();
|
||||
|
||||
for (const auto& param : const_results) {
|
||||
auto new_param = ov::as_type_ptr<const ov::op::v0::Result>(param);
|
||||
ov::element::Type fake_element_type = new_param->get_input_element_type(0);
|
||||
|
||||
const std::string& fake_name = new_param->get_input_node_ptr(0)->get_friendly_name();
|
||||
const std::string& param_name = new_param->get_friendly_name();
|
||||
const ov::PartialShape& fake_shape = new_param->get_input_partial_shape(0);
|
||||
const ov::Layout& param_layout = new_param->get_layout();
|
||||
const auto& param_names = new_param->output(0).get_tensor().get_names();
|
||||
|
||||
const auto& results = outputs();
|
||||
ob << results.size();
|
||||
|
||||
for (const auto& param : results) {
|
||||
std::stringstream ss;
|
||||
ss << fake_element_type;
|
||||
ss << param.get_element_type();
|
||||
|
||||
ob << ss.str();
|
||||
ob << fake_shape;
|
||||
ob << fake_name;
|
||||
ob << param_name;
|
||||
ob << param_layout.to_string();
|
||||
ob << param_names.size();
|
||||
for (const auto& name : param_names) {
|
||||
ob << param.get_partial_shape();
|
||||
ob << param.get_node()->get_input_node_ptr(0)->get_friendly_name();
|
||||
ob << param.get_node()->get_friendly_name();
|
||||
ob << param.get_names().size();
|
||||
for (const auto& name : param.get_names()) {
|
||||
ob << name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_graphs.front()->GetNetwork()->is_dynamic()) {
|
||||
ob << true;
|
||||
ov::pass::StreamSerialize serializer(networkModel, {}, ov::pass::Serialize::Version::UNSPECIFIED);
|
||||
serializer.run_on_model(std::const_pointer_cast<ngraph::Function>(m_network.getFunction()));
|
||||
if (is_dynamic) {
|
||||
ov::pass::StreamSerialize serializer(model, {}, ov::pass::Serialize::Version::UNSPECIFIED);
|
||||
serializer.run_on_model(m_model);
|
||||
} else {
|
||||
ob << false;
|
||||
m_graphs.front()->Export(ob);
|
||||
get_graph(0)->export_model(ob);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::Function> CompiledModel::GetExecGraphInfo() {
|
||||
if (m_graphs.empty())
|
||||
OPENVINO_THROW("[GPU] Model not loaded");
|
||||
|
||||
return m_graphs.front()->GetExecGraphInfo();
|
||||
std::shared_ptr<const ov::Model> CompiledModel::get_runtime_model() const {
|
||||
return get_graph(0)->get_runtime_model();
|
||||
}
|
||||
const std::vector<std::shared_ptr<Graph>>& CompiledModel::get_graphs() const {
|
||||
return m_graphs;
|
||||
}
|
||||
std::shared_ptr<Graph> CompiledModel::get_graph(size_t n) const {
|
||||
OPENVINO_ASSERT(m_graphs.size() >= n, "[GPU] Invalid graph idx: ", n, ". Only ", m_graphs.size(), " were created");
|
||||
return m_graphs[n];
|
||||
}
|
||||
|
||||
InferenceEngine::Parameter CompiledModel::GetConfig(const std::string &name) const {
|
||||
auto actual_name = name;
|
||||
if (LegacyAPIHelper::is_legacy_property({name, nullptr}, _plugin->IsNewAPI())) {
|
||||
actual_name = LegacyAPIHelper::convert_legacy_property({name, nullptr}).first;
|
||||
}
|
||||
|
||||
auto val = m_config.get_property(actual_name);
|
||||
if (LegacyAPIHelper::is_legacy_property({name, nullptr}, _plugin->IsNewAPI())) {
|
||||
val = LegacyAPIHelper::convert_to_legacy_property({actual_name, val}).second;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
InferenceEngine::Parameter CompiledModel::GetMetric(const std::string &name) const {
|
||||
ov::Any CompiledModel::get_property(const std::string& name) const {
|
||||
if (name == ov::supported_properties) {
|
||||
return decltype(ov::supported_properties)::value_type {
|
||||
// Metrics
|
||||
@@ -333,17 +267,20 @@ InferenceEngine::Parameter CompiledModel::GetMetric(const std::string &name) con
|
||||
ov::PropertyName{ov::execution_devices.name(), PropertyMutability::RO}
|
||||
};
|
||||
} else if (name == ov::model_name) {
|
||||
OPENVINO_ASSERT(!m_graphs.empty());
|
||||
return decltype(ov::model_name)::value_type {m_graphs[0]->getName()};
|
||||
return decltype(ov::model_name)::value_type {m_model_name};
|
||||
} else if (name == ov::loaded_from_cache) {
|
||||
return decltype(ov::loaded_from_cache)::value_type {m_loaded_from_cache};
|
||||
OPENVINO_SUPPRESS_DEPRECATED_START
|
||||
} else if (name == METRIC_KEY(SUPPORTED_METRICS)) {
|
||||
std::vector<std::string> metrics;
|
||||
metrics.push_back(METRIC_KEY(NETWORK_NAME));
|
||||
metrics.push_back(METRIC_KEY(SUPPORTED_METRICS));
|
||||
metrics.push_back(METRIC_KEY(SUPPORTED_CONFIG_KEYS));
|
||||
metrics.push_back(METRIC_KEY(OPTIMAL_NUMBER_OF_INFER_REQUESTS));
|
||||
static const std::vector<std::string> metrics {
|
||||
METRIC_KEY(NETWORK_NAME),
|
||||
METRIC_KEY(SUPPORTED_METRICS),
|
||||
METRIC_KEY(SUPPORTED_CONFIG_KEYS),
|
||||
METRIC_KEY(OPTIMAL_NUMBER_OF_INFER_REQUESTS),
|
||||
};
|
||||
IE_SET_METRIC_RETURN(SUPPORTED_METRICS, metrics);
|
||||
} else if (name == METRIC_KEY(SUPPORTED_CONFIG_KEYS)) {
|
||||
static const std::vector<std::string> configKeys {
|
||||
static const std::vector<std::string> config_keys {
|
||||
CONFIG_KEY(MODEL_PRIORITY),
|
||||
CONFIG_KEY(PERFORMANCE_HINT),
|
||||
CONFIG_KEY(PERFORMANCE_HINT_NUM_REQUESTS),
|
||||
@@ -360,21 +297,40 @@ InferenceEngine::Parameter CompiledModel::GetMetric(const std::string &name) con
|
||||
GPU_CONFIG_KEY(MAX_NUM_THREADS),
|
||||
GPU_CONFIG_KEY(ENABLE_LOOP_UNROLLING),
|
||||
};
|
||||
IE_SET_METRIC_RETURN(SUPPORTED_CONFIG_KEYS, configKeys);
|
||||
IE_SET_METRIC_RETURN(SUPPORTED_CONFIG_KEYS, config_keys);
|
||||
OPENVINO_SUPPRESS_DEPRECATED_END
|
||||
} else if (name == ov::optimal_number_of_infer_requests) {
|
||||
unsigned int nr = m_config.get_property(ov::num_streams);
|
||||
if (m_config.get_property(ov::hint::performance_mode) != ov::hint::PerformanceMode::LATENCY)
|
||||
nr *= 2;
|
||||
return decltype(ov::optimal_number_of_infer_requests)::value_type {nr};
|
||||
} else if (name == ov::execution_devices) {
|
||||
return decltype(ov::execution_devices)::value_type{m_context->getDeviceName()};
|
||||
} else {
|
||||
OPENVINO_THROW("[GPU] Unsupported CompiledModel property: ", name);
|
||||
return decltype(ov::execution_devices)::value_type{m_context->get_device_name()};
|
||||
}
|
||||
|
||||
auto actual_name = name;
|
||||
if (LegacyAPIHelper::is_legacy_property({name, nullptr}, is_new_api())) {
|
||||
actual_name = LegacyAPIHelper::convert_legacy_property({name, nullptr}).first;
|
||||
}
|
||||
|
||||
auto val = m_config.get_property(actual_name);
|
||||
if (LegacyAPIHelper::is_legacy_property({name, nullptr}, is_new_api())) {
|
||||
val = LegacyAPIHelper::convert_to_legacy_property({actual_name, val}).second;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
std::shared_ptr<InferenceEngine::RemoteContext> CompiledModel::GetContext() const {
|
||||
return m_context;
|
||||
std::shared_ptr<ov::ISyncInferRequest> CompiledModel::create_sync_infer_request() const {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "CompiledModel::create_sync_infer_request");
|
||||
OPENVINO_ASSERT(!m_graphs.empty(), "[GPU] Model not loaded");
|
||||
|
||||
for (auto& graph : m_graphs) {
|
||||
OPENVINO_ASSERT(graph != nullptr, "[GPU] Model not loaded: graph is nullptr");
|
||||
OPENVINO_ASSERT(graph->is_loaded(), "[GPU] Model not loaded: invalid graph");
|
||||
}
|
||||
|
||||
return std::make_shared<SyncInferRequest>(std::static_pointer_cast<const CompiledModel>(shared_from_this()));
|
||||
}
|
||||
|
||||
} // namespace intel_gpu
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "intel_gpu/runtime/layout.hpp"
|
||||
#include "openvino/runtime/threading/executor_manager.hpp"
|
||||
#include "openvino/runtime/exec_model_info.hpp"
|
||||
#include "openvino/pass/serialize.hpp"
|
||||
|
||||
#include "intel_gpu/graph/network.hpp"
|
||||
#include "intel_gpu/graph/serialization/binary_buffer.hpp"
|
||||
#include "intel_gpu/graph/serialization/map_serializer.hpp"
|
||||
@@ -14,10 +19,6 @@
|
||||
#include "intel_gpu/runtime/itt.hpp"
|
||||
#include "intel_gpu/plugin/graph.hpp"
|
||||
#include "intel_gpu/plugin/simple_math.hpp"
|
||||
#include "intel_gpu/plugin/infer_request.hpp"
|
||||
|
||||
#include "openvino/runtime/threading/executor_manager.hpp"
|
||||
#include "openvino/runtime/exec_model_info.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
@@ -31,36 +32,29 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
using namespace InferenceEngine;
|
||||
using namespace InferenceEngine::details;
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
Graph::Graph(InferenceEngine::CNNNetwork& network, const RemoteContextImpl::Ptr& context, const ExecutionConfig& config, uint16_t stream_id,
|
||||
InferenceEngine::InputsDataMap* inputs, InferenceEngine::OutputsDataMap* outputs)
|
||||
Graph::Graph(std::shared_ptr<ov::Model> model, const RemoteContextImpl::Ptr& context, const ExecutionConfig& config, uint16_t stream_id)
|
||||
: m_context(context)
|
||||
, m_networkName(network.getName())
|
||||
, m_config(config)
|
||||
, m_stream_id(stream_id)
|
||||
, m_state(0) {
|
||||
m_program = std::make_shared<ProgramBuilder>(network, get_engine(), config, false, false, inputs, outputs);
|
||||
if (m_program->m_max_batch > 1)
|
||||
m_config.set_property(ov::intel_gpu::max_dynamic_batch(m_program->m_max_batch));
|
||||
Build();
|
||||
, m_stream_id(stream_id) {
|
||||
auto program_builder = std::make_shared<ProgramBuilder>(model, get_engine(), config, false, false);
|
||||
m_config = program_builder->get_config();
|
||||
|
||||
build(program_builder->get_compiled_program());
|
||||
|
||||
primitiveIDs = program_builder->primitive_ids;
|
||||
prevPrimitiveIDs = program_builder->prevPrimitiveIDs;
|
||||
profilingIDs = program_builder->profiling_ids;
|
||||
perfMap = program_builder->perfMap;
|
||||
m_input_layouts = program_builder->get_input_layouts();
|
||||
}
|
||||
|
||||
Graph::Graph(cldnn::BinaryInputBuffer &ib, const RemoteContextImpl::Ptr& context, const ExecutionConfig& config, uint16_t stream_id,
|
||||
InferenceEngine::InputsDataMap* inputs, InferenceEngine::OutputsDataMap* outputs)
|
||||
Graph::Graph(cldnn::BinaryInputBuffer &ib, const RemoteContextImpl::Ptr& context, const ExecutionConfig& config, uint16_t stream_id)
|
||||
: m_context(context)
|
||||
, m_config(config)
|
||||
, m_stream_id(stream_id)
|
||||
, m_state(0) {
|
||||
m_program = std::make_shared<ProgramBuilder>(get_engine(), config, inputs, outputs);
|
||||
ib >> m_program->m_max_batch;
|
||||
if (m_program->m_max_batch > 1)
|
||||
m_config.set_property(ov::intel_gpu::max_dynamic_batch(m_program->m_max_batch));
|
||||
|
||||
, m_stream_id(stream_id) {
|
||||
bool need_onednn_engine = false;
|
||||
ib >> need_onednn_engine;
|
||||
if (need_onednn_engine) {
|
||||
@@ -71,12 +65,7 @@ Graph::Graph(cldnn::BinaryInputBuffer &ib, const RemoteContextImpl::Ptr& context
|
||||
#endif // ENABLE_ONEDNN_FOR_GPU
|
||||
}
|
||||
|
||||
ib >> m_program->inputLayouts;
|
||||
ProgramBuilder::variables_state_info_map variablesStateInfoMap;
|
||||
ib >> variablesStateInfoMap;
|
||||
for (const auto& variablesStateInfo : variablesStateInfoMap) {
|
||||
m_program->AddVariableStateInfo(variablesStateInfo.first, *variablesStateInfo.second.begin());
|
||||
}
|
||||
ib >> m_input_layouts;
|
||||
ib >> primitiveIDs;
|
||||
ib >> prevPrimitiveIDs;
|
||||
ib >> profilingIDs;
|
||||
@@ -89,71 +78,53 @@ Graph::Graph(cldnn::BinaryInputBuffer &ib, const RemoteContextImpl::Ptr& context
|
||||
perfMap[prim_id].first = prim_id;
|
||||
auto& perfEntry = perfMap[prim_id].second;
|
||||
ib >> perfEntry.layerType;
|
||||
ib >> cldnn::make_data(&perfEntry.status, sizeof(InferenceEngine::InferenceEngineProfileInfo::LayerStatus));
|
||||
ib >> cldnn::make_data(&perfEntry.status, sizeof(ov::ProfilingInfo::Status));
|
||||
perfEntry.cpu_uSec = perfEntry.realTime_uSec = 0;
|
||||
ib >> perfEntry.isCPU;
|
||||
ib >> perfEntry.parentPrimitive;
|
||||
}
|
||||
}
|
||||
ib >> outputDims;
|
||||
|
||||
size_t num_networks;
|
||||
ib >> num_networks;
|
||||
for (uint32_t i = 0; i < num_networks; ++i) {
|
||||
m_networks.emplace_back(std::make_shared<cldnn::network>(ib, get_engine().create_stream(config), get_engine(), m_stream_id == 0, i));
|
||||
}
|
||||
m_network = std::make_shared<cldnn::network>(ib, get_engine().create_stream(config), get_engine(), m_stream_id == 0, 0);
|
||||
}
|
||||
|
||||
Graph::Graph(std::shared_ptr<Graph> graph, uint16_t stream_id)
|
||||
: m_context(graph->m_context)
|
||||
, m_program(graph->m_program)
|
||||
, m_networkName(graph->m_networkName)
|
||||
, m_config(graph->m_config)
|
||||
, m_stream_id(stream_id)
|
||||
, m_state(0) {
|
||||
Build();
|
||||
, primitiveIDs(graph->primitiveIDs)
|
||||
, prevPrimitiveIDs(graph->prevPrimitiveIDs)
|
||||
, perfMap(graph->perfMap)
|
||||
, profilingIDs(graph->profilingIDs)
|
||||
, m_input_layouts(graph->m_input_layouts) {
|
||||
build(graph->get_network()->get_program());
|
||||
}
|
||||
|
||||
void Graph::UpdateLayersMaps() {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "Graph::UpdateLayersMaps");
|
||||
primitiveIDs = m_program->primitive_ids;
|
||||
prevPrimitiveIDs = m_program->prevPrimitiveIDs;
|
||||
profilingIDs = m_program->profiling_ids;
|
||||
perfMap = m_program->perfMap;
|
||||
outputDims = m_program->outputDims;
|
||||
}
|
||||
void Graph::build(std::shared_ptr<cldnn::program> program) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "Graph::build");
|
||||
|
||||
void Graph::Build() {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "Graph::Build");
|
||||
UpdateLayersMaps();
|
||||
|
||||
if (GetMaxDynamicBatchSize() > 1) {
|
||||
int m_bv_sz = m_program->GetMaxBatchSizeForSingleProgram();
|
||||
for (int b = m_bv_sz - 1; b >= 0; b--) {
|
||||
auto network = BuildNetwork(m_program->GetCompiledProgram(b));
|
||||
m_networks.insert(m_networks.begin(), network);
|
||||
}
|
||||
auto external_queue = m_context->get_external_queue();
|
||||
if (external_queue) {
|
||||
OPENVINO_ASSERT(m_config.get_property(ov::num_streams) == 1, "[GPU] Throughput streams can't be used with shared queue!");
|
||||
const auto &engine = program->get_engine();
|
||||
m_network = std::make_shared<cldnn::network>(program, engine.create_stream(m_config, external_queue), m_stream_id);
|
||||
} else {
|
||||
auto network = BuildNetwork(m_program->GetCompiledProgram());
|
||||
m_networks.emplace_back(network);
|
||||
m_network = std::make_shared<cldnn::network>(program, m_stream_id);
|
||||
}
|
||||
|
||||
GPU_DEBUG_GET_INSTANCE(debug_config);
|
||||
GPU_DEBUG_IF(!debug_config->dry_run_path.empty()) {
|
||||
CNNNetwork net(GetExecGraphInfo());
|
||||
net.serialize(debug_config->dry_run_path);
|
||||
ov::pass::Serialize(debug_config->dry_run_path, "").run_on_model(get_runtime_model());
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
GPU_DEBUG_IF(!debug_config->dump_graphs.empty() && m_stream_id == 0) {
|
||||
static int net_id = 0;
|
||||
auto steps_info = GetNetwork()->get_optimizer_passes_info();
|
||||
auto steps_info = get_network()->get_optimizer_passes_info();
|
||||
size_t step_idx = 0;
|
||||
for (auto& step : steps_info) {
|
||||
CNNNetwork net(GetExecGraphInfoByPrimitivesInfo(step.second, true));
|
||||
net.serialize(debug_config->dump_graphs + std::to_string(net_id) + "_" +
|
||||
std::to_string(step_idx) + "_" + step.first + "_graph.xml");
|
||||
auto xml_path = debug_config->dump_graphs + std::to_string(net_id) + "_" + std::to_string(step_idx) + "_" + step.first + "_graph.xml";
|
||||
ov::pass::Serialize(xml_path, "").run_on_model(get_runtime_model(step.second, true));
|
||||
step_idx++;
|
||||
}
|
||||
net_id++;
|
||||
@@ -164,73 +135,24 @@ bool Graph::use_external_queue() const {
|
||||
return m_context->get_external_queue() != nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<cldnn::network> Graph::BuildNetwork(std::shared_ptr<cldnn::program> program) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "Graph::BuildNetwork");
|
||||
std::shared_ptr<cldnn::network> network = nullptr;
|
||||
|
||||
auto externalQueue = m_context->get_external_queue();
|
||||
if (externalQueue) {
|
||||
if (m_config.get_property(ov::num_streams) != 1)
|
||||
OPENVINO_THROW("Throughput streams can't be used with shared queue!\n");
|
||||
auto &engine = m_program->get_engine();
|
||||
network = std::make_shared<cldnn::network>(program, engine.create_stream(m_config, externalQueue), m_stream_id);
|
||||
} else {
|
||||
network = std::make_shared<cldnn::network>(program, m_stream_id);
|
||||
}
|
||||
|
||||
return network;
|
||||
}
|
||||
|
||||
Graph::variable_states_map Graph::AllocateVariablesMemories() {
|
||||
Graph::variable_states_map states {};
|
||||
const auto& memStatesInfo = m_program->GetVariablesStatesInfo();
|
||||
OPENVINO_ASSERT(memStatesInfo.empty() || !GetNetwork()->is_dynamic(), "[GPU] Dynamic shapes are not supported yet for stateful models");
|
||||
for (const auto& memStateInfo : memStatesInfo) {
|
||||
std::vector<cldnn::layout> orderedLayouts {memStateInfo.second.begin(), memStateInfo.second.end()};
|
||||
std::sort(orderedLayouts.begin(), orderedLayouts.end(), [](cldnn::layout& first, cldnn::layout& second) {
|
||||
return first.batch() < second.batch();
|
||||
});
|
||||
std::vector<cldnn::network::VariableState::Ptr> memoryStates;
|
||||
memoryStates.reserve(orderedLayouts.size());
|
||||
for (const auto& layout : orderedLayouts)
|
||||
memoryStates.push_back(std::make_shared<cldnn::network::VariableState>(get_engine().allocate_memory(layout, false)));
|
||||
states.insert({memStateInfo.first, memoryStates });
|
||||
}
|
||||
return states;
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::Function> Graph::GetExecGraphInfoByPrimitivesInfo(std::vector<cldnn::primitive_info>& primitives_info,
|
||||
bool filter_const_primitives) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "Graph::GetExecGraphInfoByPrimitivesInfo");
|
||||
std::shared_ptr<ov::Model> Graph::get_runtime_model(std::vector<cldnn::primitive_info>& primitives_info, bool filter_const_primitives) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "Graph::get_runtime_model");
|
||||
if (m_config.get_property(ov::enable_profiling)) {
|
||||
try {
|
||||
// Update may throw an exception for step-by-step runtime graph dump,
|
||||
// since network->get_executed_primitives() method can't be called before network execution
|
||||
UpdatePerfStatistics();
|
||||
update_profiling_info();
|
||||
} catch (std::exception&) {
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, std::shared_ptr<ngraph::Node>> node2layer;
|
||||
std::map<std::string, std::shared_ptr<ov::Node>> node2layer;
|
||||
|
||||
ngraph::ResultVector results;
|
||||
ngraph::ParameterVector params;
|
||||
ngraph::NodeVector nodes;
|
||||
ov::ResultVector results;
|
||||
ov::ParameterVector params;
|
||||
ov::NodeVector nodes;
|
||||
|
||||
auto data_type_to_precision = [](cldnn::data_types dt) {
|
||||
switch (dt) {
|
||||
case cldnn::data_types::bin: return Precision::BIN;
|
||||
case cldnn::data_types::f32: return Precision::FP32;
|
||||
case cldnn::data_types::f16: return Precision::FP16;
|
||||
case cldnn::data_types::i32: return Precision::I32;
|
||||
case cldnn::data_types::i64: return Precision::I64;
|
||||
case cldnn::data_types::u8: return Precision::U8;
|
||||
case cldnn::data_types::i8: return Precision::I8;
|
||||
default: return Precision::UNSPECIFIED;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: Adjust output layer names to be aligned with ngraph and add new ops
|
||||
// TODO: Adjust output layer names to be aligned with ov and add new ops
|
||||
auto to_IE_type_name = [](const std::string& cldnn_name) -> std::string{
|
||||
static std::map<std::string, std::string> type_n2l {
|
||||
{ "activation", "Activation" },
|
||||
@@ -319,7 +241,7 @@ std::shared_ptr<ngraph::Function> Graph::GetExecGraphInfoByPrimitivesInfo(std::v
|
||||
return std::string((it+1), name.end());
|
||||
};
|
||||
|
||||
auto extIdMap = GetNetwork()->get_ext_id_mapping();
|
||||
auto extIdMap = get_network()->get_ext_id_mapping();
|
||||
|
||||
auto find_origin_layers = [&](const std::string& name) -> std::vector<std::string> {
|
||||
if (extIdMap.find(name) == extIdMap.end()) {
|
||||
@@ -329,7 +251,7 @@ std::shared_ptr<ngraph::Function> Graph::GetExecGraphInfoByPrimitivesInfo(std::v
|
||||
};
|
||||
|
||||
auto get_inputs = [&] (const cldnn::primitive_info& prim_info) {
|
||||
ngraph::OutputVector inputs;
|
||||
ov::OutputVector inputs;
|
||||
|
||||
auto& deps = prim_info.c_dependencies;
|
||||
|
||||
@@ -355,21 +277,21 @@ std::shared_ptr<ngraph::Function> Graph::GetExecGraphInfoByPrimitivesInfo(std::v
|
||||
return inputs;
|
||||
};
|
||||
|
||||
auto create_ngraph_node = [&](const cldnn::primitive_info& prim_info) {
|
||||
auto create_ov_node = [&](const cldnn::primitive_info& prim_info) {
|
||||
const auto& user_ids = prim_info.c_users;
|
||||
size_t output_size = user_ids.size();
|
||||
bool is_output = user_ids.empty();
|
||||
auto out_et = cldnn::data_type_to_element_type(prim_info.output_layout.data_type);
|
||||
auto out_pshape = prim_info.output_layout.get_partial_shape();
|
||||
std::shared_ptr<ngraph::Node> return_node;
|
||||
std::shared_ptr<ov::Node> return_node;
|
||||
|
||||
if (prim_info.type_id == "input_layout") {
|
||||
auto param = std::make_shared<ngraph::op::Parameter>(out_et, out_pshape);
|
||||
auto param = std::make_shared<ov::op::v0::Parameter>(out_et, out_pshape);
|
||||
params.push_back(param);
|
||||
return_node = param;
|
||||
// create additional result node if parameter is output without post reorder
|
||||
if (is_output) {
|
||||
results.emplace_back(std::make_shared<ngraph::op::Result>(return_node->get_default_output()));
|
||||
results.emplace_back(std::make_shared<ov::op::v0::Result>(return_node->get_default_output()));
|
||||
}
|
||||
} else {
|
||||
return_node = std::make_shared<ov::exec_model_info::ExecutionNode>(get_inputs(prim_info), output_size);
|
||||
@@ -378,7 +300,7 @@ std::shared_ptr<ngraph::Function> Graph::GetExecGraphInfoByPrimitivesInfo(std::v
|
||||
nodes.push_back(return_node);
|
||||
node2layer[prim_info.original_id] = return_node;
|
||||
return_node->set_output_type(0, out_et, out_pshape);
|
||||
results.emplace_back(std::make_shared<ngraph::op::Result>(return_node->get_default_output()));
|
||||
results.emplace_back(std::make_shared<ov::op::v0::Result>(return_node->get_default_output()));
|
||||
} else {
|
||||
size_t port = 0;
|
||||
for (auto& usr_id : user_ids) {
|
||||
@@ -400,14 +322,12 @@ std::shared_ptr<ngraph::Function> Graph::GetExecGraphInfoByPrimitivesInfo(std::v
|
||||
results.back()->set_friendly_name(layerName + "_result");
|
||||
|
||||
std::map<std::string, std::string> info;
|
||||
Precision prec = data_type_to_precision(prim_info.output_layout.data_type);
|
||||
Precision inference_precision = data_type_to_precision(prim_info.runtime_precision);
|
||||
info[ov::exec_model_info::OUTPUT_PRECISIONS] = prec.name();
|
||||
info[ov::exec_model_info::OUTPUT_PRECISIONS] = cldnn::data_type_to_element_type(prim_info.output_layout.data_type).get_type_name();
|
||||
info[ov::exec_model_info::LAYER_TYPE] = to_IE_type_name(prim_info.type_id);
|
||||
info[ov::exec_model_info::OUTPUT_LAYOUTS] = prim_info.layout_str;
|
||||
info[ov::exec_model_info::EXECUTION_ORDER] = std::to_string(prim_info.exec_id);
|
||||
info[ov::exec_model_info::IMPL_TYPE] = prim_info.kernel_id;
|
||||
info[ov::exec_model_info::RUNTIME_PRECISION] = inference_precision.name();
|
||||
info[ov::exec_model_info::RUNTIME_PRECISION] = cldnn::data_type_to_element_type(prim_info.runtime_precision).get_type_name();
|
||||
|
||||
std::vector<std::string> originalNames{find_origin_layers(prim_info.original_id)};
|
||||
for (auto& fused_id : prim_info.c_fused_ids) {
|
||||
@@ -493,20 +413,17 @@ std::shared_ptr<ngraph::Function> Graph::GetExecGraphInfoByPrimitivesInfo(std::v
|
||||
}
|
||||
}
|
||||
|
||||
create_ngraph_node(pi);
|
||||
create_ov_node(pi);
|
||||
}
|
||||
|
||||
return std::make_shared<ngraph::Function>(results, params, "runtime_gpu_graph");
|
||||
return std::make_shared<ov::Model>(results, params, "runtime_gpu_graph");
|
||||
}
|
||||
|
||||
// Cache blob format:
|
||||
// [ ov::intel_gpu::ProgramBuilder::inputLayouts ]
|
||||
// [ ov::intel_gpu::Graph::primitiveIDs ]
|
||||
// [ ov::intel_gpu::Graph::outputDims ]
|
||||
// [ cldnn::network ]
|
||||
void Graph::Export(cldnn::BinaryOutputBuffer &ob) {
|
||||
ob << m_program->m_max_batch;
|
||||
|
||||
void Graph::export_model(cldnn::BinaryOutputBuffer &ob) {
|
||||
bool need_onednn_engine = false;
|
||||
#ifdef ENABLE_ONEDNN_FOR_GPU
|
||||
try {
|
||||
@@ -518,8 +435,7 @@ void Graph::Export(cldnn::BinaryOutputBuffer &ob) {
|
||||
#endif // ENABLE_ONEDNN_FOR_GPU
|
||||
ob << need_onednn_engine;
|
||||
|
||||
ob << m_program->inputLayouts;
|
||||
ob << m_program->GetVariablesStatesInfo();
|
||||
ob << m_input_layouts;
|
||||
ob << primitiveIDs;
|
||||
ob << prevPrimitiveIDs;
|
||||
ob << profilingIDs;
|
||||
@@ -528,31 +444,23 @@ void Graph::Export(cldnn::BinaryOutputBuffer &ob) {
|
||||
for (auto& perf_item : perfMap) {
|
||||
ob << perf_item.first;
|
||||
ob << perf_item.second.second.layerType;
|
||||
ob << cldnn::make_data(&perf_item.second.second.status, sizeof(InferenceEngine::InferenceEngineProfileInfo::LayerStatus));
|
||||
ob << cldnn::make_data(&perf_item.second.second.status, sizeof(ov::ProfilingInfo::Status));
|
||||
ob << perf_item.second.second.isCPU;
|
||||
ob << perf_item.second.second.parentPrimitive;
|
||||
}
|
||||
}
|
||||
ob << outputDims;
|
||||
|
||||
ob << m_networks.size();
|
||||
for (const auto& net : m_networks) {
|
||||
net->save(ob);
|
||||
}
|
||||
m_network->save(ob);
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::Function> Graph::GetExecGraphInfo() {
|
||||
auto primitives_info = GetNetwork()->get_primitives_info();
|
||||
return GetExecGraphInfoByPrimitivesInfo(primitives_info, true);
|
||||
std::shared_ptr<ov::Model> Graph::get_runtime_model() {
|
||||
auto primitives_info = get_network()->get_primitives_info();
|
||||
return get_runtime_model(primitives_info, true);
|
||||
}
|
||||
|
||||
|
||||
void Graph::UpdatePerfStatistics() {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "Graph::UpdatePerfStatistics");
|
||||
if (GetNetworksCount() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
void Graph::update_profiling_info() {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "Graph::update_profiling_info");
|
||||
// Collect timings
|
||||
auto collectTimings = [](cldnn::instrumentation::profiling_info& cldnnInfo, PerfCounter& pc) {
|
||||
for (auto &interval : cldnnInfo.intervals) {
|
||||
@@ -572,8 +480,8 @@ void Graph::UpdatePerfStatistics() {
|
||||
}
|
||||
};
|
||||
|
||||
std::map<cldnn::primitive_id, cldnn::event::ptr> executedPrimitives = GetNetwork()->get_executed_primitives();
|
||||
auto allPrimitives = GetNetwork()->get_all_primitives();
|
||||
std::map<cldnn::primitive_id, cldnn::event::ptr> executedPrimitives = get_network()->get_executed_primitives();
|
||||
auto allPrimitives = get_network()->get_all_primitives();
|
||||
|
||||
// Get profiling info for all layers
|
||||
for (auto &profiledID : profilingIDs) {
|
||||
@@ -586,7 +494,7 @@ void Graph::UpdatePerfStatistics() {
|
||||
// Change status if layer wasn't executed by cldnn engine
|
||||
if (execIter == executedPrimitives.end()) {
|
||||
if (perfCount.num == 0) {
|
||||
perfCount.status = InferenceEngineProfileInfo::OPTIMIZED_OUT;
|
||||
perfCount.status = ov::ProfilingInfo::Status::OPTIMIZED_OUT;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -615,22 +523,21 @@ void Graph::UpdatePerfStatistics() {
|
||||
}
|
||||
}
|
||||
|
||||
bool Graph::IsLoaded() const {
|
||||
return GetNetwork() != nullptr;
|
||||
bool Graph::is_loaded() const {
|
||||
return get_network() != nullptr;
|
||||
}
|
||||
|
||||
std::map<std::string, InferenceEngine::InferenceEngineProfileInfo> Graph::GetPerformanceCounts() const {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "Graph::GetPerformanceCounts");
|
||||
std::map<std::string, InferenceEngine::InferenceEngineProfileInfo> result;
|
||||
std::vector<ov::ProfilingInfo> Graph::get_profiling_info() const {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "Graph::get_profiling_info");
|
||||
std::map<std::string, ov::ProfilingInfo> result;
|
||||
bool combinePrimByIRLayers = false;
|
||||
unsigned i = 0;
|
||||
auto allIds = GetNetwork()->get_all_primitive_org_ids();
|
||||
auto executedPrimitives = GetNetwork()->get_executed_primitives();
|
||||
auto primitivesInfo = GetNetwork()->get_primitives_info();
|
||||
auto extIdMap = GetNetwork()->get_ext_id_mapping();
|
||||
auto allIds = get_network()->get_all_primitive_org_ids();
|
||||
auto executedPrimitives = get_network()->get_executed_primitives();
|
||||
auto primitivesInfo = get_network()->get_primitives_info();
|
||||
auto extIdMap = get_network()->get_ext_id_mapping();
|
||||
std::map<std::string, std::string> implementation_info;
|
||||
|
||||
if (GetNetwork()->get_program() == nullptr) {
|
||||
if (get_network()->get_program() == nullptr) {
|
||||
for (auto& pi : primitivesInfo) {
|
||||
implementation_info[pi.original_id] = pi.kernel_id;
|
||||
}
|
||||
@@ -674,14 +581,12 @@ std::map<std::string, InferenceEngine::InferenceEngineProfileInfo> Graph::GetPer
|
||||
|
||||
auto& extPerfEntry = result[layerName];
|
||||
|
||||
memset(extPerfEntry.exec_type, 0, sizeof(extPerfEntry.exec_type));
|
||||
if (perfCounter.isCPU) {
|
||||
static const std::string cpuExecType("CPU");
|
||||
cpuExecType.copy(extPerfEntry.exec_type, cpuExecType.length()); // Override execType as CPU
|
||||
extPerfEntry.exec_type = "CPU";
|
||||
} else {
|
||||
std::string impl;
|
||||
if (GetNetwork()->get_program() != nullptr) {
|
||||
impl = GetNetwork()->get_implementation_info(primId);
|
||||
if (get_network()->get_program() != nullptr) {
|
||||
impl = get_network()->get_implementation_info(primId);
|
||||
} else {
|
||||
if (implementation_info.find(primId) != implementation_info.end()) {
|
||||
impl = implementation_info[primId];
|
||||
@@ -689,13 +594,13 @@ std::map<std::string, InferenceEngine::InferenceEngineProfileInfo> Graph::GetPer
|
||||
impl = "undef";
|
||||
}
|
||||
}
|
||||
impl.copy(extPerfEntry.exec_type, impl.length());
|
||||
extPerfEntry.exec_type = impl;
|
||||
}
|
||||
|
||||
extPerfEntry.execution_index = i++;
|
||||
extPerfEntry.status = perfCounter.status;
|
||||
extPerfEntry.cpu_uSec = perfCounter.cpu_avg();
|
||||
extPerfEntry.realTime_uSec = perfCounter.realTime_avg();
|
||||
extPerfEntry.cpu_time = std::chrono::microseconds(perfCounter.cpu_avg());
|
||||
extPerfEntry.real_time = std::chrono::microseconds(perfCounter.realTime_avg());
|
||||
extPerfEntry.node_name = layerName;
|
||||
|
||||
if (combinePrimByIRLayers) {
|
||||
std::string kernelId = "";
|
||||
@@ -706,8 +611,8 @@ std::map<std::string, InferenceEngine::InferenceEngineProfileInfo> Graph::GetPer
|
||||
|
||||
const auto &pc = iter->second.second;
|
||||
if (id != primId && pc.parentPrimitive == primId) {
|
||||
extPerfEntry.cpu_uSec += pc.cpu_avg();
|
||||
extPerfEntry.realTime_uSec += pc.realTime_avg();
|
||||
extPerfEntry.cpu_time += std::chrono::microseconds(pc.cpu_avg());
|
||||
extPerfEntry.real_time += std::chrono::microseconds(pc.realTime_avg());
|
||||
if (pc.realTime_avg() > kernelTime) {
|
||||
kernelTime = pc.realTime_avg();
|
||||
kernelId = id;
|
||||
@@ -716,12 +621,11 @@ std::map<std::string, InferenceEngine::InferenceEngineProfileInfo> Graph::GetPer
|
||||
}
|
||||
}
|
||||
if (!kernelId.empty()) {
|
||||
std::string impl_info = GetNetwork()->get_implementation_info(kernelId);
|
||||
std::memcpy(extPerfEntry.exec_type, &impl_info[0], impl_info.length());
|
||||
extPerfEntry.exec_type = get_network()->get_implementation_info(kernelId);
|
||||
}
|
||||
}
|
||||
|
||||
getUpperCaseName(perfCounter.layerType).copy(extPerfEntry.layer_type, perfCounter.layerType.length());
|
||||
extPerfEntry.node_type = getUpperCaseName(perfCounter.layerType);
|
||||
return true;
|
||||
};
|
||||
|
||||
@@ -769,25 +673,20 @@ std::map<std::string, InferenceEngine::InferenceEngineProfileInfo> Graph::GetPer
|
||||
auto& extPerfEntry = result[layerName];
|
||||
|
||||
if (pi.is_cpu) {
|
||||
static const std::string cpuExecType("CPU");
|
||||
memset(extPerfEntry.exec_type, 0, sizeof(extPerfEntry.exec_type));
|
||||
cpuExecType.copy(extPerfEntry.exec_type, cpuExecType.length()); // Override execType as CPU
|
||||
extPerfEntry.exec_type = "CPU";
|
||||
} else {
|
||||
std::string impl = pi.kernel_id;
|
||||
impl.copy(extPerfEntry.exec_type, impl.length());
|
||||
extPerfEntry.exec_type = pi.kernel_id;
|
||||
}
|
||||
|
||||
getUpperCaseName(pi.type_id).copy(extPerfEntry.layer_type, pi.type_id.length());
|
||||
extPerfEntry.execution_index = i++;
|
||||
extPerfEntry.status = InferenceEngineProfileInfo::LayerStatus::EXECUTED;
|
||||
extPerfEntry.cpu_uSec = cpuTime;
|
||||
extPerfEntry.realTime_uSec = deviceTime;
|
||||
extPerfEntry.node_type = getUpperCaseName(pi.type_id);
|
||||
extPerfEntry.node_name = pi.original_id;
|
||||
extPerfEntry.status = ov::ProfilingInfo::Status::EXECUTED;
|
||||
extPerfEntry.cpu_time = std::chrono::microseconds(cpuTime);
|
||||
extPerfEntry.real_time = std::chrono::microseconds(deviceTime);
|
||||
|
||||
if (pi.type_id == "input_layout") {
|
||||
const std::string input_string = "Input";
|
||||
const std::string undef_string = "undef";
|
||||
input_string.copy(extPerfEntry.layer_type, 256);
|
||||
undef_string.copy(extPerfEntry.exec_type, 256);
|
||||
extPerfEntry.node_type = "Input";
|
||||
extPerfEntry.exec_type = "undef";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -809,33 +708,33 @@ std::map<std::string, InferenceEngine::InferenceEngineProfileInfo> Graph::GetPer
|
||||
auto second_res = result.find(getClearName(p.second));
|
||||
|
||||
if (first_res != result.end() && second_res != result.end() && first_res != second_res) {
|
||||
std::swap(first_res->second.cpu_uSec, second_res->second.cpu_uSec);
|
||||
std::swap(first_res->second.realTime_uSec, second_res->second.realTime_uSec);
|
||||
std::swap(first_res->second.cpu_time, second_res->second.cpu_time);
|
||||
std::swap(first_res->second.real_time, second_res->second.real_time);
|
||||
std::swap(first_res->second.status, second_res->second.status);
|
||||
std::swap(first_res->second.exec_type, second_res->second.exec_type);
|
||||
std::swap(first_res->second.execution_index, second_res->second.execution_index);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
std::vector<ov::ProfilingInfo> res;
|
||||
for (auto& kv : result) {
|
||||
res.push_back(kv.second);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::shared_ptr<cldnn::network> Graph::GetNetwork(size_t idx) const {
|
||||
if (idx >= GetNetworksCount())
|
||||
OPENVINO_THROW("Unable to find network with id=", idx, ". Stored networks count: ", GetNetworksCount());
|
||||
|
||||
return m_networks[idx];
|
||||
std::shared_ptr<cldnn::network> Graph::get_network() const {
|
||||
return m_network;
|
||||
}
|
||||
|
||||
|
||||
std::string Graph::MapOutputName(std::string outName) const {
|
||||
auto networkOutputsIDs = GetNetwork()->get_output_ids();
|
||||
auto allPrimitiveIds = GetNetwork()->get_all_primitives();
|
||||
std::string Graph::out_name_to_internal(std::string out_port_name) const {
|
||||
auto networkOutputsIDs = get_network()->get_output_ids();
|
||||
auto allPrimitiveIds = get_network()->get_all_primitives();
|
||||
|
||||
// Find correct output ID. Start with name stored in IR.
|
||||
if (primitiveIDs.find(outName) == primitiveIDs.end()) {
|
||||
OPENVINO_THROW("output with name ", outName, " was not found in primitiveIDs");
|
||||
if (primitiveIDs.find(out_port_name) == primitiveIDs.end()) {
|
||||
OPENVINO_THROW("output with name ", out_port_name, " was not found in primitiveIDs");
|
||||
}
|
||||
std::string outputID = primitiveIDs.at(outName);
|
||||
std::string outputID = primitiveIDs.at(out_port_name);
|
||||
while (std::find(networkOutputsIDs.begin(), networkOutputsIDs.end(), outputID) == networkOutputsIDs.end()) {
|
||||
// If current ID isn't found in cldnn network outputs, get previous primitive id and try again.
|
||||
auto prim = allPrimitiveIds.find(outputID);
|
||||
@@ -852,17 +751,5 @@ std::string Graph::MapOutputName(std::string outName) const {
|
||||
return outputID;
|
||||
}
|
||||
|
||||
InferenceEngine::SizeVector Graph::GetOutputSize(std::string outName) const {
|
||||
auto res_output = outputDims.find(outName);
|
||||
|
||||
InferenceEngine::SizeVector sz;
|
||||
if (res_output != outputDims.end())
|
||||
sz = res_output->second;
|
||||
else
|
||||
sz = outputDims.at(primitiveIDs.at(outName));
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -5,8 +5,6 @@
|
||||
#include "intel_gpu/plugin/program_builder.hpp"
|
||||
#include "intel_gpu/primitives/condition.hpp"
|
||||
|
||||
#include "ie_ngraph_utils.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
@@ -16,33 +14,13 @@ const size_t idx_false = 1;
|
||||
static cldnn::condition::branch gen_branch(ProgramBuilder& p, const std::shared_ptr<ov::op::v8::If>& op, size_t idx) {
|
||||
cldnn::condition::branch branch;
|
||||
const auto& internal_body = (idx == idx_true)? op->get_then_body() : op->get_else_body();
|
||||
InferenceEngine::CNNNetwork body_network(internal_body);
|
||||
{
|
||||
// CNNNetwork change the input/output data type to fp32 when input/output data type is fp16
|
||||
// To run internal body, rollback input/output data to original one.
|
||||
size_t tidx = 0;
|
||||
auto& model_inputs = internal_body->get_parameters();
|
||||
for (auto& in : body_network.getInputsInfo()) {
|
||||
auto input_data_type = InferenceEngine::details::convertPrecision(model_inputs[tidx++]->get_output_tensor(0).get_element_type());
|
||||
if (in.second->getPrecision() != input_data_type)
|
||||
in.second->setPrecision(input_data_type);
|
||||
}
|
||||
|
||||
tidx = 0;
|
||||
for (auto& out : body_network.getOutputsInfo()) {
|
||||
const auto& model_output = internal_body->get_output_op(tidx++);
|
||||
auto output_data_type = InferenceEngine::details::convertPrecision(model_output->get_output_tensor(0).get_element_type());
|
||||
if (out.second->getPrecision() != output_data_type)
|
||||
out.second->setPrecision(output_data_type);
|
||||
}
|
||||
}
|
||||
|
||||
auto config = p.get_config();
|
||||
config.set_property(ov::intel_gpu::max_dynamic_batch(1));
|
||||
config.set_property(ov::intel_gpu::allow_new_shape_infer(op->is_dynamic()));
|
||||
|
||||
ProgramBuilder prog(body_network, p.get_engine(), config, false, false, nullptr, nullptr, p.get_task_executor(), true);
|
||||
branch.inner_program = prog.GetCompiledProgram();
|
||||
ProgramBuilder prog(internal_body, p.get_engine(), config, false, false, p.get_task_executor(), true);
|
||||
branch.inner_program = prog.get_compiled_program();
|
||||
|
||||
auto& input_map = branch.input_map;
|
||||
auto external_inputs = p.GetInputInfo(op);
|
||||
|
||||
@@ -23,11 +23,7 @@ static void CreateCommonConvertColorOp(ProgramBuilder& p, const std::shared_ptr<
|
||||
auto inputs = p.GetInputInfo(op);
|
||||
std::string layerName = layer_type_name_ID(op);
|
||||
|
||||
auto outDatatype = cldnn::element_type_to_data_type(op->get_input_element_type(0));
|
||||
auto outShape = tensor_from_dims(op->get_output_shape(0));
|
||||
outShape = { outShape.sizes()[0], outShape.sizes()[2], outShape.sizes()[3], outShape.sizes()[1] };
|
||||
|
||||
auto out_layout = cldnn::layout(outDatatype, cldnn::format::byxf, outShape);
|
||||
auto batch = op->get_input_partial_shape(0)[0];
|
||||
|
||||
auto memory_type = cldnn::convert_color::memory_type::buffer;
|
||||
if (op->get_input_node_ptr(0)->output(0).get_rt_info().count(ov::preprocess::TensorInfoMemoryType::get_type_info_static())) {
|
||||
@@ -38,25 +34,21 @@ static void CreateCommonConvertColorOp(ProgramBuilder& p, const std::shared_ptr<
|
||||
}
|
||||
}
|
||||
|
||||
if (outShape.batch[0] > 1 && memory_type == cldnn::convert_color::memory_type::image) {
|
||||
if (batch.is_static() && batch.get_length() > 1 && memory_type == cldnn::convert_color::memory_type::image) {
|
||||
std::vector<cldnn::input_info> convert_color_names;
|
||||
for (int b = 0; b < outShape.batch[0]; ++b) {
|
||||
for (int64_t b = 0; b < batch.get_length(); ++b) {
|
||||
cldnn::primitive::input_info_arr batched_inputs;
|
||||
for (size_t i = 0; i < inputs.size(); ++i) {
|
||||
batched_inputs.emplace_back(cldnn::input_info(inputs[i].pid + "_" + std::to_string(b), inputs[i].idx));
|
||||
}
|
||||
cldnn::primitive_id batched_prim_id = layerName + "_" + std::to_string(b);
|
||||
convert_color_names.emplace_back(cldnn::input_info(batched_prim_id));
|
||||
auto new_shape = outShape;
|
||||
new_shape.batch[0] = 1;
|
||||
out_layout.set_tensor(new_shape);
|
||||
|
||||
p.add_primitive(*op, cldnn::convert_color(batched_prim_id,
|
||||
batched_inputs,
|
||||
from_color,
|
||||
to_color,
|
||||
memory_type,
|
||||
out_layout));
|
||||
memory_type));
|
||||
}
|
||||
p.add_primitive(*op, cldnn::concatenation(layerName, convert_color_names, 0));
|
||||
} else {
|
||||
@@ -64,8 +56,7 @@ static void CreateCommonConvertColorOp(ProgramBuilder& p, const std::shared_ptr<
|
||||
inputs,
|
||||
from_color,
|
||||
to_color,
|
||||
memory_type,
|
||||
out_layout));
|
||||
memory_type));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
#include "intel_gpu/primitives/reorder.hpp"
|
||||
#include "intel_gpu/graph/topology.hpp"
|
||||
|
||||
#include "ie_ngraph_utils.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -54,9 +52,6 @@ static void CreateLoopOp(ProgramBuilder& p, const std::shared_ptr<Loop>& op) {
|
||||
const auto& body_inputs = op->get_function()->get_parameters();
|
||||
const auto& body_outputs = op->get_function()->get_results();
|
||||
|
||||
InferenceEngine::CNNNetwork body_network(op->get_function());
|
||||
auto networkInputs = body_network.getInputsInfo();
|
||||
auto networkOutputs = body_network.getOutputsInfo();
|
||||
// Set special body ports: current_iteration input , execution condition output
|
||||
auto special_body_ports = op->get_special_body_ports();
|
||||
|
||||
@@ -65,23 +60,17 @@ static void CreateLoopOp(ProgramBuilder& p, const std::shared_ptr<Loop>& op) {
|
||||
auto current_iteration_input = body_inputs.at(special_body_ports.current_iteration_input_idx);
|
||||
body_current_iteration_id = layer_type_name_ID(current_iteration_input);
|
||||
std::string input_name = ov::op::util::create_ie_output_name(current_iteration_input);
|
||||
const auto networkInput = networkInputs.at(input_name);
|
||||
auto precision = InferenceEngine::details::convertPrecision(current_iteration_input->get_element_type());
|
||||
networkInput->setPrecision(precision);
|
||||
}
|
||||
|
||||
cldnn::primitive_id body_execution_condition_id;
|
||||
if (special_body_ports.body_condition_output_idx >= 0) {
|
||||
auto body_condition_output = body_outputs.at(special_body_ports.body_condition_output_idx)->get_input_node_shared_ptr(0);
|
||||
body_execution_condition_id = layer_type_name_ID(body_condition_output);
|
||||
std::string output_name = ov::op::util::create_ie_output_name(body_condition_output);
|
||||
const auto networkOutput = networkOutputs.at(output_name);
|
||||
networkOutput->setPrecision(InferenceEngine::Precision::I64);
|
||||
}
|
||||
|
||||
// get body topology from ngraph function
|
||||
ProgramBuilder body_program(body_network, p.get_engine(), p.get_config(), true);
|
||||
auto body_topology = *body_program.GetTopology();
|
||||
// get body topology from ov::Model
|
||||
ProgramBuilder body_program(op->get_function(), p.get_engine(), p.get_config(), true);
|
||||
auto body_topology = *body_program.get_topology();
|
||||
|
||||
// setup input_primitive_maps/ output_primitive_maps and back_edges
|
||||
std::vector<cldnn::loop::io_primitive_map> input_primitive_maps;
|
||||
|
||||
@@ -19,122 +19,21 @@
|
||||
#include "intel_gpu/primitives/data.hpp"
|
||||
#include "intel_gpu/primitives/concatenation.hpp"
|
||||
|
||||
using namespace InferenceEngine;
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
static void CreateParameterOp(ProgramBuilder& p, const std::shared_ptr<ov::op::v0::Parameter>& op) {
|
||||
auto networkInputs = p.GetNetworkInputs();
|
||||
OPENVINO_ASSERT(networkInputs.find(op->get_friendly_name()) != networkInputs.end(),
|
||||
"[GPU] Can't find input ", op->get_friendly_name(), " in InputsDataMap");
|
||||
|
||||
auto inputInfo = networkInputs.at(op->get_friendly_name());
|
||||
// first create and add the input layout
|
||||
const auto inputDesc = inputInfo->getTensorDesc();
|
||||
InferenceEngine::Layout l = inputDesc.getLayout();
|
||||
InferenceEngine::Precision ip = inputDesc.getPrecision();
|
||||
|
||||
auto input_pshape = op->get_partial_shape();
|
||||
if (!p.use_new_shape_infer()) {
|
||||
if (input_pshape.size() < 4) {
|
||||
input_pshape.insert(input_pshape.end(), 4 - input_pshape.size(), ov::Dimension(1));
|
||||
}
|
||||
if (p.m_max_batch > 1) {
|
||||
input_pshape[0] = ov::Dimension(p.m_curBatch);
|
||||
}
|
||||
if (!p.use_new_shape_infer() && input_pshape.size() < 4) {
|
||||
input_pshape.insert(input_pshape.end(), 4 - input_pshape.size(), ov::Dimension(1));
|
||||
}
|
||||
|
||||
cldnn::format inputFormat = cldnn::format::get_default_format(input_pshape.size());
|
||||
std::vector<size_t> default_order(input_pshape.size());
|
||||
std::iota(default_order.begin(), default_order.end(), 0);
|
||||
// For legacy API we need to handle NHWC as well, so check non default order
|
||||
if (inputDesc.getBlockingDesc().getOrder() != default_order) {
|
||||
inputFormat = FormatFromLayout(l);
|
||||
}
|
||||
cldnn::format input_format = cldnn::format::get_default_format(input_pshape.size());
|
||||
auto element_type = cldnn::element_type_to_data_type(convert_to_supported_device_type(op->get_output_element_type(0)));
|
||||
|
||||
// look at the expected color format of this input
|
||||
auto inputName = layer_type_name_ID(op);
|
||||
auto preProcess = inputInfo->getPreProcess();
|
||||
size_t meanChannels = preProcess.getNumberOfChannels();
|
||||
cldnn::layout networkInputLayout(input_pshape,
|
||||
cldnn::element_type_to_data_type(op->get_output_element_type(0)),
|
||||
inputFormat);
|
||||
cldnn::primitive_id meanBlobID = inputName + ProgramBuilder::m_meanValuesTag;
|
||||
std::vector<float> meanValues;
|
||||
|
||||
if ((meanChannels > 0) &&
|
||||
(meanChannels != static_cast<size_t>(networkInputLayout.feature()))) {
|
||||
OPENVINO_THROW("Mismatched mean values channels in input ", inputName);
|
||||
}
|
||||
|
||||
switch (preProcess.getMeanVariant()) {
|
||||
case NONE:
|
||||
case MEAN_VALUE: {
|
||||
if (meanChannels > 0) {
|
||||
for (size_t c = 0; c < meanChannels; c++) {
|
||||
if (fabs(preProcess[c]->stdScale - 1.0f) > 1e-10)
|
||||
OPENVINO_THROW("not supporting stdScale yet in input ", inputName);
|
||||
meanValues.push_back(preProcess[c]->meanValue);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MEAN_IMAGE: {
|
||||
OPENVINO_ASSERT(meanChannels);
|
||||
// first merge all mean values to a single blob
|
||||
// todo make sure mean blob precision is the same as the input precision
|
||||
auto meanDims = input_pshape;
|
||||
// overwrite batches with 1
|
||||
switch (meanDims.size()) {
|
||||
case 4: meanDims[0] = 1;
|
||||
break;
|
||||
default:
|
||||
OPENVINO_THROW("Missing batch dimensions in input image");
|
||||
}
|
||||
const TensorDesc desc(Precision::FP32, meanDims.to_shape(), TensorDesc::getLayoutByDims(meanDims.to_shape()));
|
||||
TBlob<float> meanBlob(desc);
|
||||
meanBlob.allocate();
|
||||
auto meanBlobData = meanBlob.data();
|
||||
for (size_t c = 0; c < meanChannels; c++) {
|
||||
if (fabs(preProcess[c]->stdScale - 1.0f) > 1e-10)
|
||||
OPENVINO_THROW("not supporting stdScale yet in input ", inputName);
|
||||
auto channelMeanBlob = std::dynamic_pointer_cast<TBlob<float>>(preProcess[c]->meanData);
|
||||
auto channelSize = channelMeanBlob->size();
|
||||
auto channelBlobData = channelMeanBlob->data();
|
||||
for (size_t i = 0; i < channelSize; i++) {
|
||||
meanBlobData[(c * channelSize) + i] = channelBlobData[i];
|
||||
}
|
||||
}
|
||||
// then create a data primitive for the mean values
|
||||
auto meanBlobPtr = std::make_shared<TBlob<float>>(meanBlob);
|
||||
|
||||
// mean values will use external format (sub in the input format before convert to new format)
|
||||
cldnn::tensor meanBlobTensor(networkInputLayout.get_tensor());
|
||||
meanBlobTensor.batch[0] = 1; // mean values have no batches
|
||||
cldnn::layout meanBlobLayout(cldnn::data_types::f32, cldnn::format::bfyx, meanBlobTensor);
|
||||
|
||||
auto data = static_cast<const char *>(meanBlobPtr->buffer());
|
||||
|
||||
auto bufIter = p.blobMemCache.find(std::make_pair(data, meanDims.to_shape()));
|
||||
if (bufIter != p.blobMemCache.end()) {
|
||||
meanBlobID = bufIter->second;
|
||||
} else {
|
||||
auto mem = p.get_engine().allocate_memory(meanBlobLayout, false);
|
||||
cldnn::mem_lock<int8_t> tmpPointer{ mem, p.get_engine().get_service_stream() };
|
||||
auto buf = tmpPointer.data();
|
||||
auto bufSize = meanBlobLayout.bytes_count();
|
||||
|
||||
std::memcpy(&buf[0], &data[0], bufSize);
|
||||
|
||||
p.add_primitive(*op, cldnn::data(meanBlobID, mem));
|
||||
p.blobMemCache[std::make_pair(data, meanDims.to_shape())] = meanBlobID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: OPENVINO_THROW("Invalid mean variant in input ", inputName);
|
||||
break;
|
||||
}
|
||||
auto input_name = layer_type_name_ID(op);
|
||||
cldnn::layout input_layout(input_pshape, element_type, input_format);
|
||||
|
||||
auto is_convert_color_type = [](const std::shared_ptr<ov::Node> &node) {
|
||||
return ov::is_type<ov::op::v8::NV12toRGB>(node) ||
|
||||
@@ -182,80 +81,44 @@ static void CreateParameterOp(ProgramBuilder& p, const std::shared_ptr<ov::op::v
|
||||
|
||||
if (is_surface_input) {
|
||||
size_t batch = input_pshape[0].get_length();
|
||||
networkInputLayout.format = cldnn::format::nv12;
|
||||
networkInputLayout.set_partial_shape({ 1, input_pshape[3], input_pshape[1], input_pshape[2] });
|
||||
input_layout.format = cldnn::format::nv12;
|
||||
input_layout.set_partial_shape({ 1, input_pshape[1], input_pshape[2], input_pshape[3] });
|
||||
|
||||
std::string suffix = "";
|
||||
std::vector<cldnn::input_info> surfaces_inputs;
|
||||
for (size_t i = 0; i < batch; ++i) {
|
||||
if (batch > 1)
|
||||
suffix = "_" + std::to_string(i);
|
||||
std::string batched_name = inputName + suffix;
|
||||
p.inputLayouts.insert({ inputInfo->name() + suffix, networkInputLayout });
|
||||
p.add_primitive(*op, cldnn::input_layout(batched_name, networkInputLayout));
|
||||
std::string batched_name = input_name + suffix;
|
||||
p.inputLayouts.insert({ op->get_friendly_name() + suffix, input_layout });
|
||||
p.add_primitive(*op, cldnn::input_layout(batched_name, input_layout));
|
||||
|
||||
auto reorder_layout = networkInputLayout;
|
||||
auto reorder_layout = input_layout;
|
||||
reorder_layout.format = cldnn::format::bfyx;
|
||||
|
||||
auto preprocessPrimID = "reorder:" + inputName + ProgramBuilder::m_preProcessTag + suffix;
|
||||
auto reorder = cldnn::reorder(preprocessPrimID,
|
||||
auto reorder_name = "reorder:" + input_name + ProgramBuilder::m_preProcessTag + suffix;
|
||||
auto reorder = cldnn::reorder(reorder_name,
|
||||
cldnn::input_info(batched_name),
|
||||
reorder_layout);
|
||||
reorder.input_mem_type = cldnn::reorder::memory_type::surface;
|
||||
p.add_primitive(*op, reorder);
|
||||
surfaces_inputs.push_back(cldnn::input_info(preprocessPrimID));
|
||||
surfaces_inputs.emplace_back(reorder_name);
|
||||
}
|
||||
|
||||
if (batch > 1 && !is_convert_color_input)
|
||||
p.add_primitive(*op, cldnn::concatenation(inputName, surfaces_inputs, 0));
|
||||
p.add_primitive(*op, cldnn::concatenation(input_name, surfaces_inputs, 0));
|
||||
else
|
||||
p.primitive_ids[inputName] = "reorder:" + inputName + ProgramBuilder::m_preProcessTag;
|
||||
} else if (is_convert_color_input) {
|
||||
networkInputLayout.format = cldnn::format::byxf;
|
||||
|
||||
networkInputLayout.set_partial_shape({ input_pshape[0], input_pshape[3], input_pshape[1], input_pshape[2] });
|
||||
|
||||
p.inputLayouts.insert({ inputInfo->name(), networkInputLayout });
|
||||
p.add_primitive(*op, cldnn::input_layout(inputName, networkInputLayout));
|
||||
p.primitive_ids[input_name] = "reorder:" + input_name + ProgramBuilder::m_preProcessTag;
|
||||
} else {
|
||||
auto preprocessPrimID = "reorder:" + inputName + ProgramBuilder::m_preProcessTag;
|
||||
cldnn::layout inputLayout(networkInputLayout);
|
||||
auto network_input_data_type = DataTypeFromPrecision(ip);
|
||||
inputLayout.data_type = network_input_data_type;
|
||||
p.inputLayouts.insert({ inputInfo->name(), inputLayout });
|
||||
auto reorder_name = "reorder:" + input_name + ProgramBuilder::m_preProcessTag;
|
||||
p.inputLayouts.insert({ op->get_friendly_name(), input_layout });
|
||||
|
||||
p.add_primitive(*op, cldnn::input_layout(inputName, inputLayout));
|
||||
p.add_primitive(*op, cldnn::input_layout(input_name, input_layout));
|
||||
|
||||
switch (preProcess.getMeanVariant()) {
|
||||
case NONE: {
|
||||
// If mean value is not specified and the data type does not change, do not add post reorder
|
||||
if (network_input_data_type != networkInputLayout.data_type || connected_to_quantize(op)) {
|
||||
p.add_primitive(*op, cldnn::reorder(preprocessPrimID,
|
||||
cldnn::input_info(inputName),
|
||||
networkInputLayout,
|
||||
meanValues,
|
||||
cldnn::reorder_mean_mode::none), {inputName});
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MEAN_VALUE: {
|
||||
p.add_primitive(*op, cldnn::reorder(preprocessPrimID,
|
||||
cldnn::input_info(inputName),
|
||||
networkInputLayout,
|
||||
meanValues,
|
||||
cldnn::reorder_mean_mode::subtract), {inputName});
|
||||
break;
|
||||
}
|
||||
case MEAN_IMAGE: {
|
||||
p.add_primitive(*op, cldnn::reorder(preprocessPrimID,
|
||||
cldnn::input_info(inputName),
|
||||
networkInputLayout,
|
||||
meanBlobID,
|
||||
cldnn::reorder_mean_mode::subtract), {inputName});
|
||||
break;
|
||||
}
|
||||
default: OPENVINO_THROW("Invalid mean variant in input ", inputName);
|
||||
break;
|
||||
if (connected_to_quantize(op)) {
|
||||
// Techically this reorder is not needed, but for some reason it impacts layout propagation logic
|
||||
// TODO: Remove it and fix layout assignment & propagation passes
|
||||
p.add_primitive(*op, cldnn::reorder(reorder_name, cldnn::input_info(input_name), input_layout), {input_name});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,88 +12,36 @@
|
||||
#include "intel_gpu/plugin/common_utils.hpp"
|
||||
#include "intel_gpu/primitives/reorder.hpp"
|
||||
|
||||
using namespace InferenceEngine;
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
static void CreateResultOp(ProgramBuilder& p, const std::shared_ptr<ov::op::v0::Result>& op) {
|
||||
OutputsDataMap networkOutputs = p.GetNetworkOutputs();
|
||||
validate_inputs_count(op, {1});
|
||||
|
||||
auto prev = op->get_input_node_shared_ptr(0);
|
||||
NGRAPH_SUPPRESS_DEPRECATED_START
|
||||
auto inputID = ov::descriptor::get_ov_tensor_legacy_name(op->get_input_source_output(0).get_tensor());
|
||||
NGRAPH_SUPPRESS_DEPRECATED_END
|
||||
if (inputID.empty()) {
|
||||
inputID = prev->get_friendly_name();
|
||||
OPENVINO_SUPPRESS_DEPRECATED_START
|
||||
auto input_id = ov::descriptor::get_ov_tensor_legacy_name(op->get_input_source_output(0).get_tensor());
|
||||
OPENVINO_SUPPRESS_DEPRECATED_END
|
||||
if (input_id.empty()) {
|
||||
input_id = prev->get_friendly_name();
|
||||
if (prev->get_output_size() > 1) {
|
||||
inputID += "." + std::to_string(op->get_input_source_output(0).get_index());
|
||||
input_id += "." + std::to_string(op->get_input_source_output(0).get_index());
|
||||
}
|
||||
}
|
||||
auto it = networkOutputs.find(inputID);
|
||||
OPENVINO_ASSERT(it != networkOutputs.end(), "[GPU] Can't find output ", inputID, " in OutputsDataMap");
|
||||
std::string originalOutName = it->first;
|
||||
DataPtr outputData = it->second;
|
||||
|
||||
auto inputs = p.GetInputInfo(op);
|
||||
const auto outputDesc = outputData->getTensorDesc();
|
||||
auto outputlayout = outputDesc.getLayout();
|
||||
|
||||
if (ov::is_type<ov::op::v8::NV12toRGB>(prev) ||
|
||||
ov::is_type<ov::op::v8::NV12toBGR>(prev) ||
|
||||
ov::is_type<ov::op::v8::I420toRGB>(prev) ||
|
||||
ov::is_type<ov::op::v8::I420toBGR>(prev)) {
|
||||
outputlayout = NHWC;
|
||||
}
|
||||
|
||||
// TODO: add precision check once there's an outputInfo object
|
||||
if (outputlayout != NCHW &&
|
||||
// TODO: change 6d case once new layout added in IE
|
||||
outputlayout != BLOCKED &&
|
||||
outputlayout != NCDHW &&
|
||||
outputlayout != NHWC &&
|
||||
outputlayout != CHW &&
|
||||
outputlayout != NC &&
|
||||
outputlayout != C &&
|
||||
outputlayout != SCALAR) {
|
||||
OPENVINO_THROW("[GPU] Unsupported layout (", outputlayout, ") in output: ", originalOutName);
|
||||
}
|
||||
auto out_rank = op->get_output_partial_shape(0).size();
|
||||
auto out_format = cldnn::format::get_default_format(out_rank);
|
||||
std::vector<size_t> default_order(out_rank);
|
||||
std::iota(default_order.begin(), default_order.end(), 0);
|
||||
// For legacy API we need to handle NHWC as well, so check non default order
|
||||
if (outputlayout == NHWC) {
|
||||
out_format = FormatFromLayout(outputlayout);
|
||||
}
|
||||
|
||||
auto outLayerName = layer_type_name_ID(op);
|
||||
auto inputDataType = cldnn::element_type_to_data_type(op->get_input_element_type(0));
|
||||
Precision precision = outputData->getPrecision();
|
||||
auto outputDataType = DataTypeFromPrecision(precision);
|
||||
cldnn::input_info outputID = inputs[0];
|
||||
auto out_primitive_name = layer_type_name_ID(op);
|
||||
auto out_data_type = cldnn::element_type_to_data_type(convert_to_supported_device_type(op->get_input_element_type(0)));
|
||||
|
||||
// Even for result op, if reorder only performs type conversion, reorder is created in truncation mode
|
||||
if (inputDataType != outputDataType) {
|
||||
auto reorder_primitive = cldnn::reorder(outLayerName,
|
||||
outputID,
|
||||
out_format,
|
||||
outputDataType,
|
||||
std::vector<float>(),
|
||||
cldnn::reorder_mean_mode::subtract,
|
||||
cldnn::padding(),
|
||||
true);
|
||||
p.add_primitive(*op, reorder_primitive, {originalOutName});
|
||||
} else {
|
||||
auto reorder_primitive = cldnn::reorder(outLayerName,
|
||||
outputID,
|
||||
out_format,
|
||||
outputDataType);
|
||||
p.add_primitive(*op, reorder_primitive, {originalOutName});
|
||||
}
|
||||
p.outputDims[originalOutName] = outputDesc.getDims();
|
||||
p.prevPrimitiveIDs[outLayerName] = {originalOutName};
|
||||
auto reorder_primitive = cldnn::reorder(out_primitive_name,
|
||||
inputs[0],
|
||||
out_format,
|
||||
out_data_type);
|
||||
p.add_primitive(*op, reorder_primitive, {input_id, op->get_friendly_name()});
|
||||
p.prevPrimitiveIDs[out_primitive_name] = {input_id};
|
||||
}
|
||||
|
||||
REGISTER_FACTORY_IMPL(v0, Result);
|
||||
|
||||
@@ -49,10 +49,8 @@ static cldnn::mutable_data CreateAdditionalOutputData(ProgramBuilder &p, const s
|
||||
static void CreateTensorIteratorOp(ProgramBuilder &p, const std::shared_ptr<TensorIterator> &op) {
|
||||
auto inputs = p.GetInputInfo(op);
|
||||
|
||||
// get body topology from ngraph function
|
||||
InferenceEngine::CNNNetwork body_network(op->get_body());
|
||||
ProgramBuilder body_program(body_network, p.get_engine(), p.get_config(), true);
|
||||
auto body_topology = *body_program.GetTopology();
|
||||
ProgramBuilder body_program(op->get_body(), p.get_engine(), p.get_config(), true);
|
||||
auto body_topology = *body_program.get_topology();
|
||||
|
||||
// setup input_primitive_maps/ output_primitive_maps and back_edges
|
||||
const auto& loop_input_descs = op->get_input_descriptions();
|
||||
|
||||
@@ -4,16 +4,10 @@
|
||||
|
||||
#include "openvino/op/transpose.hpp"
|
||||
#include "openvino/op/constant.hpp"
|
||||
#include "openvino/op/convert.hpp"
|
||||
#include "openvino/op/nv12_to_rgb.hpp"
|
||||
#include "openvino/op/nv12_to_bgr.hpp"
|
||||
#include "openvino/op/i420_to_rgb.hpp"
|
||||
#include "openvino/op/i420_to_bgr.hpp"
|
||||
|
||||
#include "intel_gpu/plugin/program_builder.hpp"
|
||||
#include "intel_gpu/plugin/common_utils.hpp"
|
||||
#include "intel_gpu/primitives/permute.hpp"
|
||||
#include "intel_gpu/primitives/reorder.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
@@ -30,39 +24,6 @@ static void CreateTransposeOp(ProgramBuilder& p, const std::shared_ptr<ov::op::v
|
||||
order = order_constant->cast_vector<uint16_t>();
|
||||
}
|
||||
|
||||
auto is_convert_color_type_impl = [](const std::shared_ptr<ov::Node> &node) {
|
||||
return ov::is_type<ov::op::v8::NV12toRGB>(node) ||
|
||||
ov::is_type<ov::op::v8::NV12toBGR>(node) ||
|
||||
ov::is_type<ov::op::v8::I420toRGB>(node) ||
|
||||
ov::is_type<ov::op::v8::I420toBGR>(node);
|
||||
};
|
||||
|
||||
auto is_convert_color_type = [&is_convert_color_type_impl](const std::shared_ptr<ov::Node> &node) {
|
||||
if (ngraph::is_type<ov::op::v0::Convert>(node)) {
|
||||
return is_convert_color_type_impl(node->get_input_node_shared_ptr(0));
|
||||
}
|
||||
return is_convert_color_type_impl(node);
|
||||
};
|
||||
|
||||
// Handle Transpose operation related to ConvertColor operation:
|
||||
// In case of ConvertColor operation we have NHWC (byxf) input format which should be converted to
|
||||
// NCHW (bfyx) by this Permute, so we replace Permute with Reorder (to bfyx) primitve
|
||||
auto input = op->get_input_size() > 0 ? op->get_input_node_shared_ptr(0) : nullptr;
|
||||
// Handle the case ConvertColor -> FakeQuantize -> Permute
|
||||
auto input1 = input ? (input->get_input_size() > 0 ? input->get_input_node_shared_ptr(0) : nullptr) : nullptr;
|
||||
if (((input && is_convert_color_type(input)) || (input1 && is_convert_color_type(input1)))
|
||||
&& order == std::vector<uint16_t>{0, 3, 1, 2}) {
|
||||
auto precision = input->get_element_type();
|
||||
auto reorder_prim = cldnn::reorder(layerName,
|
||||
inputs[0],
|
||||
cldnn::format::bfyx,
|
||||
cldnn::element_type_to_data_type(precision),
|
||||
std::vector<float>(),
|
||||
cldnn::reorder_mean_mode::none);
|
||||
p.add_primitive(*op, reorder_prim);
|
||||
return;
|
||||
}
|
||||
|
||||
int rank = std::max(4, static_cast<int>(op->get_input_partial_shape(0).size()));
|
||||
if (order.empty()) {
|
||||
// if order size is less than 4 - fill the rest with just copy
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -25,14 +25,10 @@
|
||||
#endif
|
||||
|
||||
|
||||
using namespace InferenceEngine;
|
||||
using namespace InferenceEngine::details;
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
const cldnn::primitive_id ProgramBuilder::m_preProcessTag("_cldnn_input_preprocess");
|
||||
const cldnn::primitive_id ProgramBuilder::m_meanValuesTag("_cldnn_mean_values");
|
||||
const cldnn::primitive_id ProgramBuilder::m_preCustomLayerTag("_cldnn_custom_preprocess");
|
||||
const cldnn::primitive_id ProgramBuilder::m_postCustomLayerTag("_cldnn_custom_postprocess");
|
||||
ProgramBuilder::factories_map_t ProgramBuilder::factories_map = {};
|
||||
@@ -57,93 +53,15 @@ std::string layer_type_name_ID(const std::shared_ptr<ov::Node>& op) {
|
||||
return layer_type_name_ID(op.get());
|
||||
}
|
||||
|
||||
void ProgramBuilder::ChangeInputBatch(int batch) {
|
||||
m_curBatch = batch;
|
||||
}
|
||||
|
||||
auto getParamName = [](const std::shared_ptr<ov::Node>& param) -> std::string {
|
||||
const auto& names = param->get_output_tensor(0).get_names();
|
||||
if (!names.empty())
|
||||
return *names.begin();
|
||||
else
|
||||
return param->get_friendly_name();
|
||||
};
|
||||
|
||||
// detect the only supported dynamic shape case -
|
||||
// exactly one dimension is dynamic in input params with defined min/max interval
|
||||
bool ProgramBuilder::IsDynBatchModel(const std::shared_ptr<ov::Model>& model,
|
||||
std::map<std::string, ov::PartialShape>& shapes,
|
||||
std::map<std::string, std::pair<int64_t, int64_t>>& batch_dim) {
|
||||
for (const auto& param : model->get_parameters()) {
|
||||
auto pname = getParamName(param);
|
||||
batch_dim[pname] = { -1, -1 };
|
||||
if (param->get_output_partial_shape(0).rank().is_dynamic()) {
|
||||
return false;
|
||||
}
|
||||
ov::PartialShape pshape = param->get_output_partial_shape(0);
|
||||
bool only_batch_dynamic = pshape.size() && pshape[0].is_dynamic();
|
||||
for (size_t i = 1; i < pshape.size(); i++) {
|
||||
if (pshape[i].is_dynamic()) {
|
||||
// only support 0th dimension for legacy dynamic batch
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (only_batch_dynamic) {
|
||||
int64_t max_b = pshape[0].get_max_length();
|
||||
if (max_b > 1) {
|
||||
batch_dim[pname].first = 0;
|
||||
batch_dim[pname].second = max_b;
|
||||
pshape[0] = 1;
|
||||
} else {
|
||||
// unbounded dynamic shape should be handled with new dynamic shape path
|
||||
return false;
|
||||
}
|
||||
}
|
||||
shapes[pname] = pshape;
|
||||
}
|
||||
if (batch_dim.empty())
|
||||
return false;
|
||||
|
||||
bool dyn_shape_batch_found = false;
|
||||
// detect 1st dyn dim, mark it and continue
|
||||
auto bitr = batch_dim.begin();
|
||||
dyn_shape_batch_found = (bitr->second.first == 0);
|
||||
auto batch_val_1st = bitr->second.second;
|
||||
bitr++;
|
||||
for (; bitr != batch_dim.end(); bitr++) {
|
||||
if (bitr->second.first == 0) {
|
||||
if (bitr->second.second != batch_val_1st) {
|
||||
dyn_shape_batch_found = false;
|
||||
break;
|
||||
} else {
|
||||
dyn_shape_batch_found = true;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return dyn_shape_batch_found;
|
||||
}
|
||||
|
||||
ProgramBuilder::ProgramBuilder(InferenceEngine::CNNNetwork& network, cldnn::engine& engine, const ExecutionConfig& config,
|
||||
bool createTopologyOnly, bool partialBuild,
|
||||
InferenceEngine::InputsDataMap* inputs, InferenceEngine::OutputsDataMap* outputs,
|
||||
std::shared_ptr<ov::threading::IStreamsExecutor> task_executor, bool innerProgram)
|
||||
: m_curBatch(-1)
|
||||
, m_config(config)
|
||||
ProgramBuilder::ProgramBuilder(std::shared_ptr<ov::Model> model, cldnn::engine& engine, const ExecutionConfig& config,
|
||||
bool create_topology_only, bool partial_build,
|
||||
std::shared_ptr<ov::threading::IStreamsExecutor> task_executor, bool is_inner_program)
|
||||
: m_config(config)
|
||||
, m_engine(engine)
|
||||
, queryMode(false)
|
||||
, m_task_executor(task_executor) {
|
||||
if (m_task_executor == nullptr)
|
||||
m_task_executor = cldnn::program::make_task_executor(m_config);
|
||||
// Extract inputs/outputs info from CNNNetwork
|
||||
auto networkInputs = (inputs != nullptr) ? *inputs : network.getInputsInfo();
|
||||
auto networkOutputs = (outputs != nullptr) ? *outputs : network.getOutputsInfo();
|
||||
|
||||
auto func = network.getFunction();
|
||||
if (!func) {
|
||||
OPENVINO_THROW("Function pointer inside CNNNetwork is nullptr");
|
||||
}
|
||||
|
||||
// locate global custom kernel config
|
||||
// and auto-load kernels from it
|
||||
@@ -175,186 +93,28 @@ ProgramBuilder::ProgramBuilder(InferenceEngine::CNNNetwork& network, cldnn::engi
|
||||
auto custom_layers_config = m_config.get_property(ov::intel_gpu::config_file);
|
||||
CustomLayer::LoadFromFile(custom_layers_config, m_custom_layers, custom_layers_config.empty());
|
||||
|
||||
auto ops = func->get_ordered_ops();
|
||||
auto ops = model->get_ordered_ops();
|
||||
|
||||
bool dyn_shape_batch_found = false;
|
||||
std::map<std::string, ov::PartialShape> shapes;
|
||||
std::map<std::string, std::pair<int64_t, int64_t>> batch_dim;
|
||||
|
||||
dyn_shape_batch_found = IsDynBatchModel(func, shapes, batch_dim);
|
||||
if (dyn_shape_batch_found) {
|
||||
m_config.set_property(ov::intel_gpu::max_dynamic_batch(batch_dim.begin()->second.second));
|
||||
}
|
||||
|
||||
int m_bv_sz = GetMaxBatchSizeForSingleProgram();
|
||||
m_max_batch = static_cast<int>(m_config.get_property(ov::intel_gpu::max_dynamic_batch));
|
||||
|
||||
// Do not apply dynamic batch for inner program (only single batch is allowed)
|
||||
if (!innerProgram && (dyn_shape_batch_found || m_max_batch > 1)) {
|
||||
// compile log2 networks to serve dynamic batch requests
|
||||
for (int b = m_bv_sz - 1; b >= 0; b--) {
|
||||
inputLayouts.clear();
|
||||
outputDims.clear();
|
||||
primitive_ids.clear();
|
||||
blobMemCache.clear();
|
||||
|
||||
auto new_batch = 1U << static_cast<unsigned>(b);
|
||||
ChangeInputBatch(new_batch);
|
||||
|
||||
// clone the source model, find the batch dim
|
||||
// and reshape the model to next batch size
|
||||
auto new_func = func->clone();
|
||||
std::map<ov::Output<ov::Node>, ov::PartialShape> new_shapes;
|
||||
for (const auto& param : new_func->get_parameters()) {
|
||||
ov::PartialShape pshape = param->get_output_partial_shape(0);
|
||||
|
||||
auto pname = getParamName(param);
|
||||
auto batch_idx = batch_dim[pname].first;
|
||||
|
||||
if (batch_idx >= 0) {
|
||||
auto pshape = shapes[pname];
|
||||
pshape[batch_idx] = new_batch;
|
||||
new_shapes[param->output(0)] = pshape;
|
||||
}
|
||||
}
|
||||
new_func->reshape(new_shapes);
|
||||
{
|
||||
auto deviceInfo = engine.get_device_info();
|
||||
TransformationsPipeline transformations(m_config, deviceInfo);
|
||||
transformations.apply(new_func);
|
||||
}
|
||||
|
||||
// reshape network input/output maps accordingly
|
||||
// for correct network compilation
|
||||
for (auto& new_input : new_func->inputs()) {
|
||||
auto iname = new_input.get_node()->get_friendly_name();
|
||||
auto it = networkInputs.find(iname);
|
||||
if (it != networkInputs.end()) {
|
||||
auto shape = new_input.get_shape();
|
||||
auto l = it->second->getTensorDesc().getLayout();
|
||||
it->second->getInputData()->reshape(shape, l);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& new_output : new_func->outputs()) {
|
||||
auto iname = new_output.get_node_shared_ptr()->get_input_source_output(0).get_node_shared_ptr()->get_friendly_name();
|
||||
auto it = networkOutputs.find(iname);
|
||||
if (it != networkOutputs.end()) {
|
||||
auto shape = new_output.get_shape();
|
||||
auto l = it->second->getTensorDesc().getLayout();
|
||||
it->second->reshape(shape, l);
|
||||
}
|
||||
}
|
||||
m_programs.insert(m_programs.begin(), BuildProgram(new_func->get_ordered_ops(), networkInputs, networkOutputs,
|
||||
createTopologyOnly, partialBuild));
|
||||
}
|
||||
{
|
||||
// recompute maximal dynamic batch inputs/outputs for infer request
|
||||
// and store them into internal maps
|
||||
// same operations as above, but for maximum batch
|
||||
auto new_func = func->clone();
|
||||
std::map<ov::Output<ov::Node>, ov::PartialShape> new_shapes;
|
||||
for (const auto& param : new_func->get_parameters()) {
|
||||
ov::PartialShape pshape = param->get_output_partial_shape(0);
|
||||
|
||||
auto pname = getParamName(param);
|
||||
auto batch_idx = batch_dim[pname].first;
|
||||
|
||||
if (batch_idx >= 0) {
|
||||
auto pshape = shapes[pname];
|
||||
pshape[batch_idx] = m_max_batch;
|
||||
new_shapes[param->output(0)] = pshape;
|
||||
}
|
||||
}
|
||||
new_func->reshape(new_shapes);
|
||||
|
||||
for (auto& new_input : new_func->inputs()) {
|
||||
auto iname = new_input.get_node()->get_friendly_name();
|
||||
auto it = networkInputs.find(iname);
|
||||
if (it != networkInputs.end()) {
|
||||
auto shape = new_input.get_shape();
|
||||
auto l = it->second->getTensorDesc().getLayout();
|
||||
it->second->getInputData()->reshape(shape, l);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& new_output : new_func->outputs()) {
|
||||
auto iname = new_output.get_node_shared_ptr()->get_input_source_output(0).get_node_shared_ptr()->get_friendly_name();
|
||||
auto it = networkOutputs.find(iname);
|
||||
if (it != networkOutputs.end()) {
|
||||
auto shape = new_output.get_shape();
|
||||
auto l = it->second->getTensorDesc().getLayout();
|
||||
SizeVector old_shape = it->second->getTensorDesc().getDims();
|
||||
it->second->reshape(shape, l);
|
||||
// detect changed output batch dimension
|
||||
SizeVector new_shape = it->second->getTensorDesc().getDims();
|
||||
for (int64_t i = 0; i < static_cast<int64_t>(old_shape.size()); i++) {
|
||||
if (old_shape[i] != new_shape[i]) {
|
||||
m_output_batch_dim[iname] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_networkInputs = networkInputs;
|
||||
m_networkOutputs = networkOutputs;
|
||||
m_input_batch_dim = batch_dim;
|
||||
}
|
||||
} else {
|
||||
m_programs.emplace_back(BuildProgram(ops, networkInputs, networkOutputs, createTopologyOnly, partialBuild, innerProgram));
|
||||
}
|
||||
m_program = build(ops, create_topology_only, partial_build, is_inner_program);
|
||||
}
|
||||
|
||||
ProgramBuilder::ProgramBuilder(cldnn::engine& engine, const ExecutionConfig& config,
|
||||
InferenceEngine::InputsDataMap* inputs, InferenceEngine::OutputsDataMap* outputs)
|
||||
: m_max_batch(1)
|
||||
, m_curBatch(-1)
|
||||
, m_config(config)
|
||||
ProgramBuilder::ProgramBuilder(cldnn::engine& engine, const ExecutionConfig& config)
|
||||
: m_config(config)
|
||||
, m_engine(engine)
|
||||
, queryMode(false) {
|
||||
m_task_executor = cldnn::program::make_task_executor(m_config);
|
||||
if (inputs != nullptr)
|
||||
m_networkInputs = *inputs;
|
||||
if (outputs != nullptr)
|
||||
m_networkOutputs = *outputs;
|
||||
}
|
||||
|
||||
int ProgramBuilder::GetMaxBatchSizeForSingleProgram() {
|
||||
auto max_dynamic_batch = m_config.get_property(ov::intel_gpu::max_dynamic_batch);
|
||||
if (max_dynamic_batch > 1) {
|
||||
// calculate number of networks necessary based on binary log
|
||||
unsigned int tmp = static_cast<unsigned int>(max_dynamic_batch);
|
||||
unsigned int mask = 1U << 31;
|
||||
unsigned int ldigit = 31;
|
||||
|
||||
while (!(tmp & mask)) {
|
||||
mask >>= 1;
|
||||
ldigit--;
|
||||
}
|
||||
|
||||
return ldigit + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
std::shared_ptr<cldnn::program> ProgramBuilder::get_compiled_program() const {
|
||||
return m_program;
|
||||
}
|
||||
|
||||
std::shared_ptr<cldnn::program> ProgramBuilder::GetCompiledProgram(int program_id) {
|
||||
if (program_id >= static_cast<int32_t>(m_programs.size()))
|
||||
OPENVINO_THROW("Invalid program ID");
|
||||
|
||||
return m_programs[program_id];
|
||||
}
|
||||
|
||||
void ProgramBuilder::PrepareBuild(InferenceEngine::InputsDataMap networkInputs, InferenceEngine::OutputsDataMap networkOutputs) {
|
||||
void ProgramBuilder::prepare_build() {
|
||||
m_topology.reset(new cldnn::topology());
|
||||
m_networkInputs = networkInputs;
|
||||
m_networkOutputs = networkOutputs;
|
||||
}
|
||||
|
||||
void ProgramBuilder::CleanupBuild() {
|
||||
void ProgramBuilder::cleanup_build() {
|
||||
m_topology.reset();
|
||||
m_networkInputs.clear();
|
||||
m_networkOutputs.clear();
|
||||
#if defined(__unix__) && !defined(__ANDROID__)
|
||||
// NOTE: In linux, without malloc_trim, an amount of the memory used by compilation is not being returned to system thought they are freed.
|
||||
// (It is at least 500 MB when we perform parallel compilation)
|
||||
@@ -365,12 +125,9 @@ void ProgramBuilder::CleanupBuild() {
|
||||
#endif
|
||||
}
|
||||
|
||||
std::shared_ptr<cldnn::program> ProgramBuilder::BuildProgram(const std::vector<std::shared_ptr<ov::Node>>& ops,
|
||||
InferenceEngine::InputsDataMap networkInputs,
|
||||
InferenceEngine::OutputsDataMap networkOutputs,
|
||||
bool createTopologyOnly, bool partialBuild, bool innerProgram) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "ProgramBuilder::BuildProgram");
|
||||
// std::cout << "BuildProgram " << createTopologyOnly << ", " << partialBuild << ", " << innerProgram << std::endl;
|
||||
std::shared_ptr<cldnn::program> ProgramBuilder::build(const std::vector<std::shared_ptr<ov::Node>>& ops,
|
||||
bool create_topology_only, bool partial_build, bool is_inner_program) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "ProgramBuilder::build");
|
||||
// In the case of inner program, allow_new_shape_infer flag is setted by outside of program.
|
||||
// So, do not check allow_new_shape_infer for inner program build
|
||||
for (const auto& op : ops) {
|
||||
@@ -380,22 +137,22 @@ std::shared_ptr<cldnn::program> ProgramBuilder::BuildProgram(const std::vector<s
|
||||
}
|
||||
}
|
||||
|
||||
if (innerProgram) {
|
||||
if (is_inner_program) {
|
||||
allow_new_shape_infer = (m_config.get_property(ov::intel_gpu::allow_new_shape_infer) || allow_new_shape_infer);
|
||||
}
|
||||
|
||||
m_config.set_property(ov::intel_gpu::partial_build_program(partialBuild));
|
||||
m_config.set_property(ov::intel_gpu::partial_build_program(partial_build));
|
||||
m_config.set_property(ov::intel_gpu::optimize_data(true));
|
||||
m_config.set_property(ov::intel_gpu::allow_new_shape_infer(allow_new_shape_infer));
|
||||
|
||||
PrepareBuild(networkInputs, networkOutputs);
|
||||
prepare_build();
|
||||
{
|
||||
GPU_DEBUG_DEFINE_MEM_LOGGER("CreateSingleLayerPrimitives");
|
||||
for (const auto& op : ops) {
|
||||
CreateSingleLayerPrimitive(*m_topology, op);
|
||||
}
|
||||
}
|
||||
if (createTopologyOnly) {
|
||||
if (create_topology_only) {
|
||||
return {};
|
||||
} else {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "ProgramBuilder::CreateProgram");
|
||||
@@ -403,20 +160,20 @@ std::shared_ptr<cldnn::program> ProgramBuilder::BuildProgram(const std::vector<s
|
||||
try {
|
||||
program = cldnn::program::build_program(m_engine, *m_topology, m_config, get_task_executor());
|
||||
} catch (std::exception& e) {
|
||||
OPENVINO_ASSERT(false, "GPU program build failed!\n", e.what());
|
||||
OPENVINO_ASSERT(false, "[GPU] ProgramBuilder build failed!\n", e.what());
|
||||
}
|
||||
CleanupBuild();
|
||||
cleanup_build();
|
||||
|
||||
return program;
|
||||
}
|
||||
}
|
||||
|
||||
bool ProgramBuilder::IsOpSupported(const InferenceEngine::CNNNetwork& network, const std::shared_ptr<ov::Node>& op) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "ProgramBuilder::IsOpSupported");
|
||||
bool ProgramBuilder::is_op_supported(const std::shared_ptr<ov::Node>& op) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "ProgramBuilder::is_op_supported");
|
||||
cldnn::topology topology;
|
||||
try {
|
||||
// Query mode disables checks that input primitives are created,
|
||||
// as IsOpSupported method is called for each operation separately
|
||||
// as is_op_supported method is called for each operation separately
|
||||
// So we just ensure that inputs count is valid for given operation
|
||||
EnableQueryMode();
|
||||
// Creating topology object for each operation is supposed to be more time-consuming than
|
||||
@@ -425,14 +182,14 @@ bool ProgramBuilder::IsOpSupported(const InferenceEngine::CNNNetwork& network, c
|
||||
// add any ugly macro/templates to apply single function to multiple cases.
|
||||
// 2. We also check parameters of each operation, which means we have more
|
||||
// reliable results of QueryNetwork call.
|
||||
PrepareBuild(network.getInputsInfo(), network.getOutputsInfo());
|
||||
prepare_build();
|
||||
allow_new_shape_infer = requires_new_shape_infer(*op);
|
||||
CreateSingleLayerPrimitive(topology, op);
|
||||
CleanupBuild();
|
||||
cleanup_build();
|
||||
DisableQueryMode();
|
||||
} catch (std::exception&) {
|
||||
// Exception means that an operation or some of it's parameters are not supported
|
||||
CleanupBuild();
|
||||
cleanup_build();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -505,7 +262,7 @@ void ProgramBuilder::init_profile_info(const cldnn::primitive& prim) {
|
||||
perfMap[prim.id].first = prim.id;
|
||||
auto& perfEntry = perfMap[prim.id].second;
|
||||
perfEntry.layerType = prim.origin_op_type_name;
|
||||
perfEntry.status = InferenceEngine::InferenceEngineProfileInfo::LayerStatus::EXECUTED;
|
||||
perfEntry.status = ov::ProfilingInfo::Status::EXECUTED;
|
||||
perfEntry.cpu_uSec = perfEntry.realTime_uSec = 0;
|
||||
perfEntry.isCPU = false;
|
||||
perfEntry.parentPrimitive = prim.origin_op_name;
|
||||
|
||||
@@ -2,67 +2,36 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <memory>
|
||||
#include "intel_gpu/plugin/remote_allocators.hpp"
|
||||
#include "intel_gpu/plugin/remote_blob.hpp"
|
||||
|
||||
using namespace InferenceEngine;
|
||||
using namespace InferenceEngine::gpu;
|
||||
using namespace InferenceEngine::details;
|
||||
#include "intel_gpu/plugin/remote_tensor.hpp"
|
||||
#include "intel_gpu/plugin/remote_context.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
void RemoteAllocator::regLockedBlob(void* handle, const RemoteBlobImpl* blob) {
|
||||
std::lock_guard<RemoteAllocator> locker(*this);
|
||||
auto iter = m_lockedBlobs.find(handle);
|
||||
if (iter == m_lockedBlobs.end()) {
|
||||
m_lockedBlobs.emplace(handle, blob);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteAllocator::unlock(void* handle) noexcept {
|
||||
std::lock_guard<RemoteAllocator> locker(*this);
|
||||
auto iter = m_lockedBlobs.find(handle);
|
||||
if (iter != m_lockedBlobs.end()) {
|
||||
iter->second->unlock();
|
||||
m_lockedBlobs.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void* USMHostAllocator::lock(void* handle, InferenceEngine::LockOp) noexcept {
|
||||
if (!_usm_host_blob)
|
||||
return nullptr;
|
||||
void* USMHostAllocator::allocate(const size_t bytes, const size_t /* alignment */) noexcept {
|
||||
try {
|
||||
return _usm_host_blob->get();
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
void USMHostAllocator::unlock(void* handle) noexcept {}
|
||||
|
||||
void* USMHostAllocator::alloc(size_t size) noexcept {
|
||||
try {
|
||||
auto td = TensorDesc(Precision::U8, SizeVector{size}, InferenceEngine::Layout::C);
|
||||
ParamMap params = {{GPU_PARAM_KEY(SHARED_MEM_TYPE), GPU_PARAM_VALUE(USM_HOST_BUFFER)}};
|
||||
_usm_host_blob = std::dynamic_pointer_cast<USMBlob>(_context->CreateBlob(td, params));
|
||||
_usm_host_blob->allocate();
|
||||
if (!getBlobImpl(_usm_host_blob.get())->is_allocated()) {
|
||||
return nullptr;
|
||||
ov::AnyMap params = { ov::intel_gpu::shared_mem_type(ov::intel_gpu::SharedMemType::USM_HOST_BUFFER) };
|
||||
_usm_host_tensor = _context->create_tensor(ov::element::u8, {bytes}, params);
|
||||
if (auto casted = std::dynamic_pointer_cast<RemoteTensorImpl>(_usm_host_tensor._ptr)) {
|
||||
return casted->get_original_memory()->get_internal_params().mem;
|
||||
}
|
||||
return _usm_host_blob->get();
|
||||
} catch (...) {
|
||||
return nullptr;
|
||||
} catch (std::exception&) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool USMHostAllocator::free(void* handle) noexcept {
|
||||
bool USMHostAllocator::deallocate(void* /* handle */, const size_t /* bytes */, size_t /* alignment */) noexcept {
|
||||
try {
|
||||
_usm_host_blob = nullptr;
|
||||
} catch(...) { }
|
||||
_usm_host_tensor = {nullptr, nullptr};
|
||||
} catch (std::exception&) { }
|
||||
return true;
|
||||
}
|
||||
|
||||
bool USMHostAllocator::is_equal(const USMHostAllocator& other) const {
|
||||
return other._usm_host_tensor != nullptr && _usm_host_tensor != nullptr && other._usm_host_tensor._ptr == _usm_host_tensor._ptr;
|
||||
}
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
@@ -1,300 +0,0 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <memory>
|
||||
#include "intel_gpu/plugin/remote_context.hpp"
|
||||
#include "intel_gpu/plugin/remote_blob.hpp"
|
||||
#include "intel_gpu/plugin/remote_allocators.hpp"
|
||||
#include "intel_gpu/plugin/plugin.hpp"
|
||||
#include "intel_gpu/runtime/itt.hpp"
|
||||
|
||||
using namespace InferenceEngine;
|
||||
using namespace InferenceEngine::gpu;
|
||||
using namespace InferenceEngine::details;
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
RemoteBlobImpl::RemoteBlobImpl(InferenceEngine::gpu::ClContext::Ptr context,
|
||||
cldnn::stream& stream,
|
||||
const cldnn::layout& layout,
|
||||
cldnn::shared_handle mem,
|
||||
cldnn::shared_surface surf,
|
||||
uint32_t plane,
|
||||
BlobType mem_type)
|
||||
: m_allocator(std::make_shared<RemoteAllocator>())
|
||||
, m_context(context)
|
||||
, m_stream(stream)
|
||||
, m_mem(mem)
|
||||
, m_surf(surf)
|
||||
, m_plane(plane)
|
||||
, m_layout(layout)
|
||||
, m_mem_type(mem_type)
|
||||
, m_hash(0)
|
||||
, m_memory_object(nullptr)
|
||||
, lockedCounter(0)
|
||||
, lockedHolder(nullptr)
|
||||
, _handle(nullptr) {
|
||||
if (supports_caching()) {
|
||||
m_hash = cldnn::hash_combine(0, m_mem);
|
||||
m_hash = cldnn::hash_combine(m_hash, m_surf);
|
||||
m_hash = cldnn::hash_combine(m_hash, plane);
|
||||
m_hash = cldnn::hash_combine(m_hash, static_cast<std::underlying_type<cldnn::format::type>::type>(layout.format));
|
||||
m_hash = cldnn::hash_combine(m_hash, static_cast<std::underlying_type<cldnn::data_types>::type>(layout.data_type));
|
||||
for (auto& d : layout.get_shape()) {
|
||||
m_hash = cldnn::hash_combine(m_hash, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnyMap RemoteBlobImpl::getParams() const {
|
||||
OPENVINO_ASSERT(is_allocated(), "[GPU] Can't get RemoteBlob params as blob wasn't allocated properly");
|
||||
auto params = m_memory_object->get_internal_params();
|
||||
|
||||
switch (m_mem_type) {
|
||||
case BlobType::BT_BUF_INTERNAL:
|
||||
case BlobType::BT_BUF_SHARED:
|
||||
return{
|
||||
{ GPU_PARAM_KEY(SHARED_MEM_TYPE), GPU_PARAM_VALUE(OCL_BUFFER) },
|
||||
{ GPU_PARAM_KEY(OCL_CONTEXT), params.context },
|
||||
{ GPU_PARAM_KEY(MEM_HANDLE), params.mem }
|
||||
};
|
||||
case BlobType::BT_USM_SHARED:
|
||||
return{
|
||||
{ GPU_PARAM_KEY(SHARED_MEM_TYPE), GPU_PARAM_VALUE(USM_USER_BUFFER) },
|
||||
{ GPU_PARAM_KEY(OCL_CONTEXT), params.context },
|
||||
{ GPU_PARAM_KEY(MEM_HANDLE), params.mem }
|
||||
};
|
||||
case BlobType::BT_USM_HOST_INTERNAL:
|
||||
return{
|
||||
{ GPU_PARAM_KEY(SHARED_MEM_TYPE), GPU_PARAM_VALUE(USM_HOST_BUFFER) },
|
||||
{ GPU_PARAM_KEY(OCL_CONTEXT), params.context },
|
||||
{ GPU_PARAM_KEY(MEM_HANDLE), params.mem }
|
||||
};
|
||||
case BlobType::BT_USM_DEVICE_INTERNAL:
|
||||
return{
|
||||
{ GPU_PARAM_KEY(SHARED_MEM_TYPE), GPU_PARAM_VALUE(USM_DEVICE_BUFFER) },
|
||||
{ GPU_PARAM_KEY(OCL_CONTEXT), params.context },
|
||||
{ GPU_PARAM_KEY(MEM_HANDLE), params.mem }
|
||||
};
|
||||
#ifdef _WIN32
|
||||
case BlobType::BT_DX_BUF_SHARED:
|
||||
return{
|
||||
{ GPU_PARAM_KEY(SHARED_MEM_TYPE), GPU_PARAM_VALUE(DX_BUFFER) },
|
||||
{ GPU_PARAM_KEY(OCL_CONTEXT), params.context },
|
||||
{ GPU_PARAM_KEY(VA_DEVICE), params.user_device },
|
||||
{ GPU_PARAM_KEY(MEM_HANDLE), params.mem },
|
||||
{ GPU_PARAM_KEY(DEV_OBJECT_HANDLE), params.surface }
|
||||
};
|
||||
#endif
|
||||
case BlobType::BT_IMG_SHARED:
|
||||
return{
|
||||
{ GPU_PARAM_KEY(SHARED_MEM_TYPE), GPU_PARAM_VALUE(OCL_IMAGE2D) },
|
||||
{ GPU_PARAM_KEY(OCL_CONTEXT), params.context },
|
||||
{ GPU_PARAM_KEY(MEM_HANDLE), params.mem }
|
||||
};
|
||||
case BlobType::BT_SURF_SHARED:
|
||||
return{
|
||||
{ GPU_PARAM_KEY(SHARED_MEM_TYPE), GPU_PARAM_VALUE(VA_SURFACE) },
|
||||
{ GPU_PARAM_KEY(OCL_CONTEXT), params.context },
|
||||
{ GPU_PARAM_KEY(VA_DEVICE), params.user_device },
|
||||
{ GPU_PARAM_KEY(MEM_HANDLE), params.mem },
|
||||
{ GPU_PARAM_KEY(DEV_OBJECT_HANDLE), params.surface },
|
||||
{ GPU_PARAM_KEY(VA_PLANE), params.plane }
|
||||
};
|
||||
default:
|
||||
OPENVINO_THROW("Unsupported shared object type ", static_cast<int>(m_mem_type));
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteBlobImpl::setShape(const SizeVector& dims) {
|
||||
if (ov::shape_size(dims) > m_memory_object->count()) {
|
||||
OPENVINO_ASSERT(!is_shared(), "Cannot call setShape for Blobs created on top of preallocated memory if shape was increased.");
|
||||
if (!deallocate()) {
|
||||
OPENVINO_THROW("Cannot deallocate blob while an attempt to enlarge blob area in setShape.");
|
||||
}
|
||||
|
||||
m_layout.set_partial_shape(ov::PartialShape{dims});
|
||||
|
||||
allocate();
|
||||
}
|
||||
}
|
||||
|
||||
bool RemoteBlobImpl::deallocate() noexcept {
|
||||
m_memory_object.reset();
|
||||
return m_memory_object == nullptr;
|
||||
}
|
||||
|
||||
bool RemoteBlobImpl::is_allocated() const noexcept {
|
||||
return m_memory_object != nullptr;
|
||||
}
|
||||
|
||||
bool RemoteBlobImpl::is_locked() const noexcept {
|
||||
return lockedHolder != nullptr;
|
||||
}
|
||||
|
||||
void RemoteBlobImpl::allocate() {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "RemoteBlobImpl::Allocate");
|
||||
|
||||
auto context = get_context_impl(m_context);
|
||||
auto enable_caching = supports_caching();
|
||||
|
||||
if (enable_caching) {
|
||||
m_memory_object = context->try_get_cached_memory(m_hash);
|
||||
if (m_memory_object)
|
||||
return;
|
||||
}
|
||||
|
||||
auto& engine = context->get_engine();
|
||||
|
||||
switch (m_mem_type) {
|
||||
case BlobType::BT_BUF_INTERNAL: {
|
||||
m_memory_object = engine.allocate_memory(m_layout, cldnn::allocation_type::cl_mem);
|
||||
break;
|
||||
}
|
||||
case BlobType::BT_USM_HOST_INTERNAL: {
|
||||
m_memory_object = engine.allocate_memory(m_layout, cldnn::allocation_type::usm_host);
|
||||
break;
|
||||
}
|
||||
case BlobType::BT_USM_DEVICE_INTERNAL: {
|
||||
m_memory_object = engine.allocate_memory(m_layout, cldnn::allocation_type::usm_device);
|
||||
break;
|
||||
}
|
||||
case BlobType::BT_BUF_SHARED: {
|
||||
m_memory_object = engine.share_buffer(m_layout, m_mem);
|
||||
break;
|
||||
}
|
||||
case BlobType::BT_USM_SHARED: {
|
||||
m_memory_object = engine.share_usm(m_layout, m_mem);
|
||||
break;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
case BlobType::BT_SURF_SHARED: {
|
||||
m_memory_object = engine.share_surface(m_layout, m_mem, m_plane);
|
||||
break;
|
||||
}
|
||||
case BlobType::BT_DX_BUF_SHARED: {
|
||||
m_memory_object = engine.share_dx_buffer(m_layout, m_mem);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
case BlobType::BT_SURF_SHARED: {
|
||||
m_memory_object = engine.share_surface(m_layout, m_surf, m_plane);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case BlobType::BT_IMG_SHARED: {
|
||||
m_memory_object = engine.share_image(m_layout, m_mem);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
m_memory_object.reset();
|
||||
}
|
||||
|
||||
if (enable_caching)
|
||||
context->add_to_cache(m_hash, m_memory_object);
|
||||
}
|
||||
|
||||
const std::shared_ptr<IAllocator>& RemoteBlobImpl::getAllocator() const noexcept {
|
||||
return m_allocator;
|
||||
};
|
||||
|
||||
std::string RemoteBlobImpl::getDeviceName() const noexcept {
|
||||
return m_context->getDeviceName();
|
||||
};
|
||||
|
||||
std::shared_ptr<InferenceEngine::RemoteContext> RemoteBlobImpl::getContext() const noexcept {
|
||||
return m_context;
|
||||
}
|
||||
|
||||
void RemoteBlobImpl::reinterpret(const cldnn::layout& new_layout) {
|
||||
OPENVINO_ASSERT(m_memory_object->size() >= new_layout.bytes_count(),
|
||||
"[GPU] Can't reinterpret blob to the size bigger than allocated memory buffer",
|
||||
" (", m_memory_object->size(), " vs ", new_layout.bytes_count(), ")");
|
||||
m_layout = new_layout;
|
||||
}
|
||||
|
||||
void RemoteBlobImpl::lock() const {
|
||||
if (!is_allocated()) {
|
||||
OPENVINO_THROW("[GPU] Remote blob can't be locked as it's not allocated");
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> locker(lockedMutex);
|
||||
if (lockedCounter == 0) {
|
||||
lockedHolder = std::unique_ptr<cldnn::mem_lock<uint8_t>>(new cldnn::mem_lock<uint8_t>(m_memory_object, m_stream));
|
||||
auto ptr = lockedHolder->data();
|
||||
_handle = reinterpret_cast<void*>(ptr);
|
||||
auto casted_allocator = std::dynamic_pointer_cast<RemoteAllocator>(m_allocator);
|
||||
OPENVINO_ASSERT(casted_allocator, "[GPU] Invalid remote allocator type");
|
||||
casted_allocator->regLockedBlob(_handle, this);
|
||||
}
|
||||
lockedCounter++;
|
||||
}
|
||||
|
||||
void RemoteBlobImpl::unlock() const {
|
||||
std::lock_guard<std::mutex> locker(lockedMutex);
|
||||
lockedCounter--;
|
||||
if (lockedCounter == 0)
|
||||
lockedHolder.reset();
|
||||
}
|
||||
|
||||
LockedMemory<void> RemoteBlobImpl::buffer() noexcept {
|
||||
try {
|
||||
lock();
|
||||
return LockedMemory<void>(m_allocator.get(), _handle, 0);
|
||||
} catch (...) {
|
||||
return LockedMemory<void>(nullptr, nullptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
LockedMemory<const void> RemoteBlobImpl::cbuffer() const noexcept {
|
||||
try {
|
||||
lock();
|
||||
return LockedMemory<const void>(m_allocator.get(), _handle, 0);
|
||||
} catch (...) {
|
||||
return LockedMemory<const void>(nullptr, nullptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
LockedMemory<void> RemoteBlobImpl::rwmap() noexcept {
|
||||
try {
|
||||
lock();
|
||||
return LockedMemory<void>(m_allocator.get(), _handle, 0);
|
||||
} catch (...) {
|
||||
return LockedMemory<void>(nullptr, nullptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
LockedMemory<const void> RemoteBlobImpl::rmap() const noexcept {
|
||||
try {
|
||||
lock();
|
||||
return LockedMemory<const void>(m_allocator.get(), _handle, 0);
|
||||
} catch (...) {
|
||||
return LockedMemory<const void>(nullptr, nullptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
LockedMemory<void> RemoteBlobImpl::wmap() noexcept {
|
||||
try {
|
||||
lock();
|
||||
return LockedMemory<void>(m_allocator.get(), _handle, 0);
|
||||
} catch (...) {
|
||||
return LockedMemory<void>(nullptr, nullptr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool RemoteBlobImpl::is_shared() const {
|
||||
return m_mem_type == BlobType::BT_BUF_SHARED ||
|
||||
m_mem_type == BlobType::BT_USM_SHARED ||
|
||||
m_mem_type == BlobType::BT_IMG_SHARED ||
|
||||
m_mem_type == BlobType::BT_SURF_SHARED ||
|
||||
m_mem_type == BlobType::BT_DX_BUF_SHARED;
|
||||
}
|
||||
|
||||
bool RemoteBlobImpl::supports_caching() const {
|
||||
return is_shared();
|
||||
}
|
||||
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
@@ -2,118 +2,186 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <memory>
|
||||
#include "openvino/runtime/intel_gpu/remote_properties.hpp"
|
||||
#include "openvino/runtime/make_tensor.hpp"
|
||||
#include "intel_gpu/plugin/remote_context.hpp"
|
||||
#include "intel_gpu/plugin/remote_blob.hpp"
|
||||
#include "intel_gpu/plugin/remote_tensor.hpp"
|
||||
#include "intel_gpu/plugin/remote_allocators.hpp"
|
||||
#include "intel_gpu/runtime/itt.hpp"
|
||||
#include "intel_gpu/runtime/device_query.hpp"
|
||||
|
||||
using namespace InferenceEngine;
|
||||
using namespace InferenceEngine::gpu;
|
||||
using namespace InferenceEngine::details;
|
||||
#include <memory>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
RemoteContextImpl::RemoteContextImpl(std::string device_name, std::vector<cldnn::device::ptr> devices)
|
||||
: m_va_display(nullptr)
|
||||
, m_external_queue(nullptr)
|
||||
, m_type(ContextType::OCL)
|
||||
, m_device_name(std::move(device_name))
|
||||
, m_memory_cache(cache_capacity) {
|
||||
namespace {
|
||||
|
||||
template <typename Type>
|
||||
Type extract_object(const ov::AnyMap& params, const ov::Property<Type>& p) {
|
||||
auto itrHandle = params.find(p.name());
|
||||
OPENVINO_ASSERT(itrHandle != params.end(), "[GPU] No parameter ", p.name(), " found in parameters map");
|
||||
ov::Any res = itrHandle->second;
|
||||
return res.as<Type>();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
RemoteContextImpl::RemoteContextImpl(const std::string& device_name, std::vector<cldnn::device::ptr> devices) : m_device_name(device_name) {
|
||||
OPENVINO_ASSERT(devices.size() == 1, "[GPU] Currently context can be created for single device only");
|
||||
// TODO: Parameterize this based on plugin config and compilation options
|
||||
auto engine_type = cldnn::engine_types::ocl;
|
||||
auto runtime_type = cldnn::runtime_types::ocl;
|
||||
const auto engine_type = cldnn::engine_types::ocl;
|
||||
const auto runtime_type = cldnn::runtime_types::ocl;
|
||||
|
||||
m_engine = cldnn::engine::create(engine_type, runtime_type, devices.front());
|
||||
|
||||
GPU_DEBUG_LOG << "Initialize RemoteContext for " << m_device_name << " (" << m_engine->get_device_info().dev_name << ")" << std::endl;
|
||||
init_properties();
|
||||
}
|
||||
|
||||
RemoteContextImpl::RemoteContextImpl(const std::vector<RemoteContextImpl::Ptr>& known_contexts, const AnyMap& params)
|
||||
: m_va_display(nullptr)
|
||||
, m_external_queue(nullptr)
|
||||
, m_type(ContextType::OCL)
|
||||
, m_memory_cache(cache_capacity) {
|
||||
gpu_handle_param _context_id = nullptr;
|
||||
gpu_handle_param _va_device = nullptr;
|
||||
RemoteContextImpl::RemoteContextImpl(const std::map<std::string, RemoteContextImpl::Ptr>& known_contexts, const AnyMap& params) {
|
||||
gpu_handle_param context_id = nullptr;
|
||||
int ctx_device_id = 0;
|
||||
int target_tile_id = -1;
|
||||
|
||||
if (params.size()) {
|
||||
// parameter map is non-empty
|
||||
std::string contextTypeStr = extract_object<std::string>(params, GPU_PARAM_KEY(CONTEXT_TYPE));
|
||||
auto ctx_type = extract_object(params, ov::intel_gpu::context_type);
|
||||
|
||||
if (GPU_PARAM_VALUE(OCL) == contextTypeStr) {
|
||||
_context_id = extract_object<gpu_handle_param>(params, GPU_PARAM_KEY(OCL_CONTEXT));
|
||||
if (ctx_type == ov::intel_gpu::ContextType::OCL) {
|
||||
context_id = extract_object(params, ov::intel_gpu::ocl_context);
|
||||
OPENVINO_ASSERT(context_id != nullptr, "[GPU] Can't create shared OCL context as user handle is nullptr! Params:\n", params);
|
||||
|
||||
if (params.find(GPU_PARAM_KEY(OCL_QUEUE)) != params.end())
|
||||
m_external_queue = extract_object<gpu_handle_param>(params, GPU_PARAM_KEY(OCL_QUEUE));
|
||||
if (params.find(ov::intel_gpu::ocl_queue.name()) != params.end()) {
|
||||
m_external_queue = extract_object(params, ov::intel_gpu::ocl_queue);
|
||||
}
|
||||
|
||||
if (params.find(GPU_PARAM_KEY(OCL_CONTEXT_DEVICE_ID)) != params.end())
|
||||
ctx_device_id = extract_object<int>(params, GPU_PARAM_KEY(OCL_CONTEXT_DEVICE_ID));
|
||||
} else if (GPU_PARAM_VALUE(VA_SHARED) == contextTypeStr) {
|
||||
m_va_display = _va_device = extract_object<gpu_handle_param>(params, GPU_PARAM_KEY(VA_DEVICE));
|
||||
m_type = ContextType::DEV_SHARED;
|
||||
if (params.find(ov::intel_gpu::ocl_context_device_id.name()) != params.end())
|
||||
ctx_device_id = extract_object(params, ov::intel_gpu::ocl_context_device_id);
|
||||
} else if (ctx_type == ov::intel_gpu::ContextType::VA_SHARED) {
|
||||
m_va_display = extract_object(params, ov::intel_gpu::va_device);
|
||||
OPENVINO_ASSERT(m_va_display != nullptr, "[GPU] Can't create shared VA/DX context as user handle is nullptr! Params:\n", params);
|
||||
m_type = ContextType::VA_SHARED;
|
||||
} else {
|
||||
OPENVINO_THROW("Invalid execution context type", contextTypeStr);
|
||||
OPENVINO_THROW("Invalid execution context type", ctx_type);
|
||||
}
|
||||
auto tile_id_itr = params.find(GPU_PARAM_KEY(TILE_ID));
|
||||
if (tile_id_itr != params.end()) {
|
||||
target_tile_id = tile_id_itr->second.as<int>();
|
||||
if (params.find(ov::intel_gpu::tile_id.name()) != params.end()) {
|
||||
target_tile_id = extract_object(params, ov::intel_gpu::tile_id);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Parameterize this based on plugin config and compilation options
|
||||
auto engine_type = cldnn::engine_types::ocl;
|
||||
auto runtime_type = cldnn::runtime_types::ocl;
|
||||
const auto engine_type = cldnn::engine_types::ocl;
|
||||
const auto runtime_type = cldnn::runtime_types::ocl;
|
||||
|
||||
// Use actual runtime and engine types
|
||||
cldnn::device_query device_query(engine_type, runtime_type, _context_id, _va_device, ctx_device_id, target_tile_id);
|
||||
cldnn::device_query device_query(engine_type, runtime_type, context_id, m_va_display, ctx_device_id, target_tile_id);
|
||||
auto device_map = device_query.get_available_devices();
|
||||
|
||||
OPENVINO_ASSERT(device_map.size() == 1, "[GPU] Only one device expected in case of context sharing");
|
||||
OPENVINO_ASSERT(device_map.size() == 1, "[GPU] Exactly one device expected in case of context sharing, but ", device_map.size(), " found");
|
||||
|
||||
m_engine = cldnn::engine::create(engine_type, runtime_type, device_map.begin()->second);
|
||||
m_device_name = get_device_name(known_contexts, m_engine->get_device());
|
||||
|
||||
GPU_DEBUG_LOG << "Initialize RemoteContext for " << m_device_name << " (" << m_engine->get_device_info().dev_name << ")" << std::endl;
|
||||
|
||||
init_properties();
|
||||
}
|
||||
|
||||
AnyMap RemoteContextImpl::get_params() const {
|
||||
AnyMap ret = { { GPU_PARAM_KEY(OCL_CONTEXT), m_engine->get_user_context() } };
|
||||
void RemoteContextImpl::init_properties() {
|
||||
properties = { ov::intel_gpu::ocl_context(m_engine->get_user_context()) };
|
||||
|
||||
switch (m_type) {
|
||||
case OCL:
|
||||
ret[GPU_PARAM_KEY(CONTEXT_TYPE)] = GPU_PARAM_VALUE(OCL);
|
||||
ret[GPU_PARAM_KEY(OCL_QUEUE)] = static_cast<gpu_handle_param>(m_external_queue);
|
||||
case ContextType::OCL:
|
||||
properties.insert(ov::intel_gpu::context_type(ov::intel_gpu::ContextType::OCL));
|
||||
properties.insert(ov::intel_gpu::ocl_queue(m_external_queue));
|
||||
break;
|
||||
case DEV_SHARED:
|
||||
ret[GPU_PARAM_KEY(CONTEXT_TYPE)] = GPU_PARAM_VALUE(VA_SHARED);
|
||||
ret[GPU_PARAM_KEY(VA_DEVICE)] = m_va_display;
|
||||
case ContextType::VA_SHARED:
|
||||
properties.insert(ov::intel_gpu::context_type(ov::intel_gpu::ContextType::VA_SHARED));
|
||||
properties.insert(ov::intel_gpu::va_device(m_va_display));
|
||||
break;
|
||||
default:
|
||||
OPENVINO_THROW("Unsupported shared context type ", m_type);
|
||||
OPENVINO_THROW("[GPU] Unsupported shared context type ", m_type);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
const ov::AnyMap& RemoteContextImpl::get_property() const {
|
||||
return properties;
|
||||
}
|
||||
|
||||
std::shared_ptr<RemoteContextImpl> RemoteContextImpl::get_this_shared_ptr() {
|
||||
return std::static_pointer_cast<RemoteContextImpl>(shared_from_this());
|
||||
}
|
||||
|
||||
ov::SoPtr<ov::ITensor> RemoteContextImpl::create_host_tensor(const ov::element::Type type, const ov::Shape& shape) {
|
||||
if (m_engine->use_unified_shared_memory()) {
|
||||
USMHostAllocator allocator(get_this_shared_ptr());
|
||||
return { ov::make_tensor(type, shape, allocator), nullptr };
|
||||
} else {
|
||||
return { ov::make_tensor(type, shape), nullptr };
|
||||
}
|
||||
}
|
||||
|
||||
ov::SoPtr<ov::IRemoteTensor> RemoteContextImpl::create_tensor(const ov::element::Type& type, const ov::Shape& shape, const ov::AnyMap& params) {
|
||||
if (params.empty()) {
|
||||
// user wants plugin to allocate tensor by itself and return handle
|
||||
return { create_buffer(type, shape), nullptr };
|
||||
} else {
|
||||
// user will supply shared object handle
|
||||
auto mem_type = extract_object(params, ov::intel_gpu::shared_mem_type);
|
||||
|
||||
bool is_usm = mem_type == ov::intel_gpu::SharedMemType::USM_HOST_BUFFER ||
|
||||
mem_type == ov::intel_gpu::SharedMemType::USM_DEVICE_BUFFER ||
|
||||
mem_type == ov::intel_gpu::SharedMemType::USM_USER_BUFFER;
|
||||
|
||||
OPENVINO_ASSERT(!is_usm || m_engine->use_unified_shared_memory(),
|
||||
"[GPU] Can't create USM tensor as USM is not supported (or manually disabled) on current device");
|
||||
|
||||
if (ov::intel_gpu::SharedMemType::VA_SURFACE == mem_type) {
|
||||
check_if_shared();
|
||||
return { reuse_surface(type, shape, params), nullptr };
|
||||
} else if (ov::intel_gpu::SharedMemType::USM_HOST_BUFFER == mem_type) {
|
||||
return { create_usm(type, shape, TensorType::BT_USM_HOST_INTERNAL), nullptr };
|
||||
} else if (ov::intel_gpu::SharedMemType::USM_DEVICE_BUFFER == mem_type) {
|
||||
return { create_usm(type, shape, TensorType::BT_USM_DEVICE_INTERNAL), nullptr };
|
||||
} else {
|
||||
TensorType tensor_type;
|
||||
cldnn::shared_handle mem = nullptr;
|
||||
|
||||
if (ov::intel_gpu::SharedMemType::OCL_BUFFER == mem_type) {
|
||||
tensor_type = TensorType::BT_BUF_SHARED;
|
||||
mem = extract_object(params, ov::intel_gpu::mem_handle);
|
||||
} else if (ov::intel_gpu::SharedMemType::USM_USER_BUFFER == mem_type) {
|
||||
tensor_type = TensorType::BT_USM_SHARED;
|
||||
mem = extract_object(params, ov::intel_gpu::mem_handle);
|
||||
} else if (ov::intel_gpu::SharedMemType::OCL_IMAGE2D == mem_type) {
|
||||
tensor_type = TensorType::BT_IMG_SHARED;
|
||||
mem = extract_object(params, ov::intel_gpu::mem_handle);
|
||||
#ifdef _WIN32
|
||||
} else if (ov::intel_gpu::SharedMemType::DX_BUFFER == mem_type) {
|
||||
tensor_type = TensorType::BT_DX_BUF_SHARED;
|
||||
mem = extract_object(params, ov::intel_gpu::dev_object_handle);
|
||||
check_if_shared();
|
||||
#endif
|
||||
} else {
|
||||
OPENVINO_THROW("[GPU] Unsupported shared object type ", mem_type);
|
||||
}
|
||||
|
||||
return { reuse_memory(type, shape, mem, tensor_type), nullptr };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For external contexts we try to match underlying handles with default contexts created by plugin to find device name
|
||||
std::string RemoteContextImpl::get_device_name(const std::vector<RemoteContextImpl::Ptr>& known_contexts,
|
||||
const cldnn::device::ptr current_device) {
|
||||
std::string RemoteContextImpl::get_device_name(const std::map<std::string, RemoteContextImpl::Ptr>& known_contexts,
|
||||
const cldnn::device::ptr current_device) const {
|
||||
std::string device_name = "GPU";
|
||||
for (auto& c : known_contexts) {
|
||||
if (c->get_engine().get_device()->is_same(current_device)) {
|
||||
device_name = c->get_device_name();
|
||||
if (c.second->get_engine().get_device()->is_same(current_device)) {
|
||||
device_name = c.second->get_device_name();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return device_name;
|
||||
}
|
||||
|
||||
std::string RemoteContextImpl::get_device_name() const noexcept {
|
||||
const std::string& RemoteContextImpl::get_device_name() const {
|
||||
return m_device_name;
|
||||
}
|
||||
|
||||
@@ -130,161 +198,35 @@ void RemoteContextImpl::add_to_cache(size_t hash, cldnn::memory::ptr memory) {
|
||||
m_memory_cache.add(hash, memory);
|
||||
}
|
||||
|
||||
InferenceEngine::RemoteBlob::Ptr RemoteContextImpl::reuse_surface(InferenceEngine::gpu::ClContext::Ptr public_context,
|
||||
const InferenceEngine::TensorDesc& desc,
|
||||
const InferenceEngine::ParamMap& params) {
|
||||
using namespace InferenceEngine;
|
||||
auto& stream = m_engine->get_service_stream();
|
||||
uint32_t plane = extract_object<uint32_t>(params, GPU_PARAM_KEY(VA_PLANE));
|
||||
std::shared_ptr<ov::IRemoteTensor> RemoteContextImpl::reuse_surface(const ov::element::Type type, const ov::Shape& shape, const ov::AnyMap& params) {
|
||||
uint32_t plane = extract_object(params, ov::intel_gpu::va_plane);
|
||||
|
||||
#ifdef _WIN32
|
||||
cldnn::shared_handle surf = extract_object<cldnn::shared_handle>(params, GPU_PARAM_KEY(DEV_OBJECT_HANDLE));
|
||||
cldnn::shared_handle surf = extract_object(params, ov::intel_gpu::dev_object_handle);
|
||||
return std::make_shared<RemoteTensorImpl>(get_this_shared_ptr(), shape, type, TensorType::BT_SURF_SHARED, surf, 0, plane);
|
||||
#else
|
||||
cldnn::shared_surface surf = extract_object<cldnn::shared_surface>(params, GPU_PARAM_KEY(DEV_OBJECT_HANDLE));
|
||||
cldnn::shared_surface surf = extract_object(params, ov::intel_gpu::dev_object_handle);
|
||||
return std::make_shared<RemoteTensorImpl>(get_this_shared_ptr(), shape, type, TensorType::BT_SURF_SHARED, nullptr, surf, plane);
|
||||
#endif
|
||||
|
||||
cldnn::layout layout(DataTypeFromPrecision(desc.getPrecision()),
|
||||
ImageFormatFromLayout(desc.getLayout()),
|
||||
tensor_from_dims(desc.getDims()));
|
||||
|
||||
#ifdef _WIN32
|
||||
auto blob = std::make_shared<RemoteD3DSurface>(public_context, stream,
|
||||
desc, layout, surf, 0, plane,
|
||||
BlobType::BT_SURF_SHARED);
|
||||
#else
|
||||
auto blob = std::make_shared<RemoteVASurface>(public_context, stream,
|
||||
desc, layout, nullptr, surf, plane,
|
||||
BlobType::BT_SURF_SHARED);
|
||||
#endif
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
InferenceEngine::RemoteBlob::Ptr RemoteContextImpl::reuse_memory(InferenceEngine::gpu::ClContext::Ptr public_context,
|
||||
const InferenceEngine::TensorDesc& desc,
|
||||
cldnn::shared_handle mem,
|
||||
BlobType blob_type) {
|
||||
auto& stream = m_engine->get_service_stream();
|
||||
|
||||
cldnn::layout layout(DataTypeFromPrecision(desc.getPrecision()),
|
||||
FormatFromLayout(desc.getLayout()),
|
||||
tensor_from_dims(desc.getDims()));
|
||||
|
||||
switch (blob_type) {
|
||||
case BlobType::BT_BUF_SHARED: {
|
||||
return std::make_shared<RemoteCLbuffer>(public_context, stream, desc, layout, mem, 0, 0, blob_type);
|
||||
}
|
||||
case BlobType::BT_USM_SHARED: {
|
||||
return std::make_shared<RemoteUSMbuffer>(public_context, stream, desc, layout, mem, 0, 0, blob_type);
|
||||
}
|
||||
case BlobType::BT_IMG_SHARED: {
|
||||
layout.format = ImageFormatFromLayout(desc.getLayout());
|
||||
return std::make_shared<RemoteCLImage2D>(public_context, stream, desc, layout, mem, 0, 0, blob_type);
|
||||
}
|
||||
#ifdef _WIN32
|
||||
case BlobType::BT_DX_BUF_SHARED: {
|
||||
return std::make_shared<RemoteD3DBuffer>(public_context, stream, desc, layout, mem, 0, 0, blob_type);
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
std::shared_ptr<ov::IRemoteTensor> RemoteContextImpl::reuse_memory(const ov::element::Type type,
|
||||
const ov::Shape& shape,
|
||||
cldnn::shared_handle mem,
|
||||
TensorType tensor_type) {
|
||||
return std::make_shared<RemoteTensorImpl>(get_this_shared_ptr(), shape, type, tensor_type, mem);
|
||||
}
|
||||
|
||||
InferenceEngine::RemoteBlob::Ptr RemoteContextImpl::create_buffer(InferenceEngine::gpu::ClContext::Ptr public_context,
|
||||
const InferenceEngine::TensorDesc& desc) {
|
||||
cldnn::layout layout(DataTypeFromPrecision(desc.getPrecision()),
|
||||
FormatFromLayout(desc.getLayout()),
|
||||
tensor_from_dims(desc.getDims()));
|
||||
auto& stream = m_engine->get_service_stream();
|
||||
return std::make_shared<RemoteCLbuffer>(public_context,
|
||||
stream,
|
||||
desc,
|
||||
layout,
|
||||
nullptr, 0, 0,
|
||||
BlobType::BT_BUF_INTERNAL);
|
||||
std::shared_ptr<ov::IRemoteTensor> RemoteContextImpl::create_buffer(const ov::element::Type type, const ov::Shape& shape) {
|
||||
return std::make_shared<RemoteTensorImpl>(get_this_shared_ptr(), shape, type, TensorType::BT_BUF_INTERNAL);
|
||||
}
|
||||
|
||||
InferenceEngine::RemoteBlob::Ptr RemoteContextImpl::create_usm(InferenceEngine::gpu::ClContext::Ptr public_context,
|
||||
const InferenceEngine::TensorDesc& desc,
|
||||
BlobType alloc_type) {
|
||||
cldnn::layout layout(DataTypeFromPrecision(desc.getPrecision()),
|
||||
FormatFromLayout(desc.getLayout()),
|
||||
tensor_from_dims(desc.getDims()));
|
||||
auto& stream = m_engine->get_service_stream();
|
||||
|
||||
return std::make_shared<RemoteUSMbuffer>(public_context,
|
||||
stream,
|
||||
desc,
|
||||
layout,
|
||||
nullptr, 0, 0,
|
||||
alloc_type);
|
||||
std::shared_ptr<ov::IRemoteTensor> RemoteContextImpl::create_usm(const ov::element::Type type, const ov::Shape& shape, TensorType alloc_type) {
|
||||
return std::make_shared<RemoteTensorImpl>(get_this_shared_ptr(), shape, type, alloc_type);
|
||||
}
|
||||
|
||||
void RemoteContextImpl::check_if_shared() {
|
||||
OPENVINO_ASSERT(m_type == RemoteContextImpl::ContextType::DEV_SHARED, "[GPU] Shared context is required to to share this type of memory");
|
||||
}
|
||||
|
||||
InferenceEngine::MemoryBlob::Ptr RemoteContextImpl::create_host_blob(InferenceEngine::gpu::ClContext::Ptr public_context,
|
||||
const InferenceEngine::TensorDesc& desc) {
|
||||
if (m_engine->use_unified_shared_memory())
|
||||
return std::dynamic_pointer_cast<InferenceEngine::MemoryBlob>(make_blob_with_precision(desc, std::make_shared<USMHostAllocator>(public_context)));
|
||||
else
|
||||
return std::dynamic_pointer_cast<InferenceEngine::MemoryBlob>(make_blob_with_precision(desc));
|
||||
}
|
||||
|
||||
InferenceEngine::RemoteBlob::Ptr RemoteContextImpl::create_blob(InferenceEngine::gpu::ClContext::Ptr public_context,
|
||||
const InferenceEngine::TensorDesc& desc,
|
||||
const InferenceEngine::ParamMap& params) {
|
||||
using namespace InferenceEngine;
|
||||
if (params.empty()) {
|
||||
// user wants plugin to allocate blob by itself and return handle
|
||||
return create_buffer(public_context, desc);
|
||||
} else {
|
||||
// user will supply shared object handle
|
||||
std::string mem_type = extract_object<std::string>(params, GPU_PARAM_KEY(SHARED_MEM_TYPE));
|
||||
|
||||
bool is_usm = mem_type == GPU_PARAM_VALUE(USM_HOST_BUFFER) ||
|
||||
mem_type == GPU_PARAM_VALUE(USM_DEVICE_BUFFER) ||
|
||||
mem_type == GPU_PARAM_VALUE(USM_USER_BUFFER);
|
||||
|
||||
OPENVINO_ASSERT(!is_usm || m_engine->use_unified_shared_memory(),
|
||||
"[GPU] Can't create USM tensor as USM is not supported (or manually disabled) on current device");
|
||||
|
||||
if (GPU_PARAM_VALUE(VA_SURFACE) == mem_type) {
|
||||
check_if_shared();
|
||||
return reuse_surface(public_context, desc, params);
|
||||
} else if (GPU_PARAM_VALUE(USM_HOST_BUFFER) == mem_type) {
|
||||
return create_usm(public_context, desc, BlobType::BT_USM_HOST_INTERNAL);
|
||||
} else if (GPU_PARAM_VALUE(USM_DEVICE_BUFFER) == mem_type) {
|
||||
return create_usm(public_context, desc, BlobType::BT_USM_DEVICE_INTERNAL);
|
||||
} else {
|
||||
BlobType blob_type;
|
||||
cldnn::shared_handle mem = nullptr;
|
||||
|
||||
if (GPU_PARAM_VALUE(OCL_BUFFER) == mem_type) {
|
||||
blob_type = BlobType::BT_BUF_SHARED;
|
||||
mem = extract_object<cldnn::shared_handle>(params, GPU_PARAM_KEY(MEM_HANDLE));
|
||||
} else if (GPU_PARAM_VALUE(USM_USER_BUFFER) == mem_type) {
|
||||
blob_type = BlobType::BT_USM_SHARED;
|
||||
mem = extract_object<cldnn::shared_handle>(params, GPU_PARAM_KEY(MEM_HANDLE));
|
||||
} else if (GPU_PARAM_VALUE(OCL_IMAGE2D) == mem_type) {
|
||||
blob_type = BlobType::BT_IMG_SHARED;
|
||||
mem = extract_object<cldnn::shared_handle>(params, GPU_PARAM_KEY(MEM_HANDLE));
|
||||
#ifdef _WIN32
|
||||
} else if (GPU_PARAM_VALUE(DX_BUFFER) == mem_type) {
|
||||
blob_type = BlobType::BT_DX_BUF_SHARED;
|
||||
mem = extract_object<cldnn::shared_handle>(params, GPU_PARAM_KEY(DEV_OBJECT_HANDLE));
|
||||
check_if_shared();
|
||||
#endif
|
||||
} else {
|
||||
OPENVINO_ASSERT(false, "[GPU] Unsupported shared object type ", mem_type);
|
||||
}
|
||||
|
||||
return reuse_memory(public_context, desc, mem, blob_type);
|
||||
}
|
||||
}
|
||||
void RemoteContextImpl::check_if_shared() const {
|
||||
OPENVINO_ASSERT(m_type == ContextType::VA_SHARED, "[GPU] Shared context is required to to share this type of memory");
|
||||
}
|
||||
|
||||
} // namespace intel_gpu
|
||||
|
||||
@@ -0,0 +1,272 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "intel_gpu/plugin/remote_context.hpp"
|
||||
#include "intel_gpu/plugin/remote_tensor.hpp"
|
||||
#include "intel_gpu/plugin/remote_allocators.hpp"
|
||||
#include "intel_gpu/plugin/plugin.hpp"
|
||||
#include "intel_gpu/runtime/itt.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
RemoteTensorImpl::RemoteTensorImpl(RemoteContextImpl::Ptr context,
|
||||
const ov::Shape& shape,
|
||||
const ov::element::Type& element_type,
|
||||
TensorType mem_type,
|
||||
cldnn::shared_handle mem,
|
||||
cldnn::shared_surface surf,
|
||||
uint32_t plane)
|
||||
: m_context(context)
|
||||
, m_element_type(element_type)
|
||||
, m_shape(shape)
|
||||
, m_layout(make_layout(element_type, shape))
|
||||
, m_mem_type(mem_type)
|
||||
, m_mem(mem)
|
||||
, m_surf(surf)
|
||||
, m_plane(plane) {
|
||||
if (supports_caching()) {
|
||||
m_hash = cldnn::hash_combine(0, m_mem);
|
||||
m_hash = cldnn::hash_combine(m_hash, m_surf);
|
||||
m_hash = cldnn::hash_combine(m_hash, plane);
|
||||
m_hash = cldnn::hash_combine(m_hash, m_shape.size());
|
||||
m_hash = cldnn::hash_combine(m_hash, element_type.hash());
|
||||
for (const auto& d : m_shape) {
|
||||
m_hash = cldnn::hash_combine(m_hash, d);
|
||||
}
|
||||
}
|
||||
|
||||
update_strides();
|
||||
allocate();
|
||||
init_properties();
|
||||
}
|
||||
|
||||
RemoteTensorImpl::~RemoteTensorImpl() {
|
||||
deallocate();
|
||||
}
|
||||
|
||||
const ov::element::Type& RemoteTensorImpl::get_element_type() const {
|
||||
return m_element_type;
|
||||
}
|
||||
|
||||
const ov::Shape& RemoteTensorImpl::get_shape() const {
|
||||
return m_shape;
|
||||
}
|
||||
|
||||
void RemoteTensorImpl::update_strides() {
|
||||
if (m_element_type.bitwidth() < 8)
|
||||
return;
|
||||
auto& shape = get_shape();
|
||||
m_strides.clear();
|
||||
if (!shape.empty()) {
|
||||
m_strides.resize(shape.size());
|
||||
m_strides.back() = m_element_type.size();
|
||||
std::copy(shape.rbegin(), shape.rend() - 1, m_strides.rbegin() + 1);
|
||||
std::partial_sum(m_strides.rbegin(), m_strides.rend(), m_strides.rbegin(), std::multiplies<size_t>());
|
||||
}
|
||||
}
|
||||
|
||||
const ov::Strides& RemoteTensorImpl::get_strides() const {
|
||||
return m_strides;
|
||||
}
|
||||
|
||||
const AnyMap& RemoteTensorImpl::get_properties() const {
|
||||
return m_properties;
|
||||
}
|
||||
|
||||
void RemoteTensorImpl::set_shape(ov::Shape shape) {
|
||||
m_layout.set_partial_shape(ov::PartialShape{shape});
|
||||
m_shape = shape;
|
||||
|
||||
if (ov::shape_size(shape) > m_memory_object->count()) {
|
||||
OPENVINO_ASSERT(!is_shared(), "Cannot call setShape for Tensor created on top of preallocated memory if shape was increased.");
|
||||
if (!deallocate()) {
|
||||
OPENVINO_THROW("Cannot deallocate tensor while an attempt to enlarge tensor area in setShape.");
|
||||
}
|
||||
|
||||
allocate();
|
||||
}
|
||||
}
|
||||
|
||||
bool RemoteTensorImpl::deallocate() noexcept {
|
||||
m_memory_object.reset();
|
||||
return m_memory_object == nullptr;
|
||||
}
|
||||
|
||||
bool RemoteTensorImpl::is_allocated() const noexcept {
|
||||
return m_memory_object != nullptr;
|
||||
}
|
||||
|
||||
void RemoteTensorImpl::allocate() {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "RemoteTensorImpl::Allocate");
|
||||
|
||||
auto context = std::dynamic_pointer_cast<RemoteContextImpl>(m_context);
|
||||
auto enable_caching = supports_caching();
|
||||
|
||||
if (enable_caching) {
|
||||
m_memory_object = context->try_get_cached_memory(m_hash);
|
||||
if (m_memory_object)
|
||||
return;
|
||||
}
|
||||
|
||||
auto& engine = context->get_engine();
|
||||
|
||||
switch (m_mem_type) {
|
||||
case TensorType::BT_BUF_INTERNAL: {
|
||||
m_memory_object = engine.allocate_memory(m_layout, cldnn::allocation_type::cl_mem);
|
||||
break;
|
||||
}
|
||||
case TensorType::BT_USM_HOST_INTERNAL: {
|
||||
m_memory_object = engine.allocate_memory(m_layout, cldnn::allocation_type::usm_host);
|
||||
break;
|
||||
}
|
||||
case TensorType::BT_USM_DEVICE_INTERNAL: {
|
||||
m_memory_object = engine.allocate_memory(m_layout, cldnn::allocation_type::usm_device);
|
||||
break;
|
||||
}
|
||||
case TensorType::BT_BUF_SHARED: {
|
||||
m_memory_object = engine.share_buffer(m_layout, m_mem);
|
||||
break;
|
||||
}
|
||||
case TensorType::BT_USM_SHARED: {
|
||||
m_memory_object = engine.share_usm(m_layout, m_mem);
|
||||
break;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
case TensorType::BT_SURF_SHARED: {
|
||||
m_layout.format = cldnn::format::nv12; // Other formats are not supported
|
||||
m_memory_object = engine.share_surface(m_layout, m_mem, m_plane);
|
||||
break;
|
||||
}
|
||||
case TensorType::BT_DX_BUF_SHARED: {
|
||||
m_memory_object = engine.share_dx_buffer(m_layout, m_mem);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
case TensorType::BT_SURF_SHARED: {
|
||||
m_layout.format = cldnn::format::nv12; // Other formats are not supported
|
||||
m_memory_object = engine.share_surface(m_layout, m_surf, m_plane);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case TensorType::BT_IMG_SHARED: {
|
||||
m_layout.format = cldnn::format::nv12; // Other formats are not supported
|
||||
m_memory_object = engine.share_image(m_layout, m_mem);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
m_memory_object.reset();
|
||||
}
|
||||
|
||||
if (enable_caching)
|
||||
context->add_to_cache(m_hash, m_memory_object);
|
||||
}
|
||||
|
||||
const std::string& RemoteTensorImpl::get_device_name() const {
|
||||
return m_context->get_device_name();
|
||||
}
|
||||
|
||||
bool RemoteTensorImpl::is_shared() const {
|
||||
return m_mem_type == TensorType::BT_BUF_SHARED ||
|
||||
m_mem_type == TensorType::BT_USM_SHARED ||
|
||||
m_mem_type == TensorType::BT_IMG_SHARED ||
|
||||
m_mem_type == TensorType::BT_SURF_SHARED ||
|
||||
m_mem_type == TensorType::BT_DX_BUF_SHARED;
|
||||
}
|
||||
|
||||
bool RemoteTensorImpl::supports_caching() const {
|
||||
return is_shared();
|
||||
}
|
||||
|
||||
bool RemoteTensorImpl::is_surface() const noexcept {
|
||||
return m_mem_type == TensorType::BT_SURF_SHARED ||
|
||||
m_mem_type == TensorType::BT_IMG_SHARED ||
|
||||
m_mem_type == TensorType::BT_DX_BUF_SHARED;
|
||||
}
|
||||
|
||||
cldnn::memory::ptr RemoteTensorImpl::get_memory() const {
|
||||
auto engine = m_memory_object->get_engine();
|
||||
return engine->reinterpret_buffer(*m_memory_object, m_layout);
|
||||
}
|
||||
|
||||
cldnn::memory::ptr RemoteTensorImpl::get_original_memory() const {
|
||||
return m_memory_object;
|
||||
}
|
||||
|
||||
std::shared_ptr<RemoteContextImpl> RemoteTensorImpl::get_context() const {
|
||||
return m_context;
|
||||
}
|
||||
|
||||
void RemoteTensorImpl::init_properties() {
|
||||
OPENVINO_ASSERT(is_allocated(), "[GPU] Can't initialize RemoteTensorImpl parameters as memory was not allocated");
|
||||
auto params = m_memory_object->get_internal_params();
|
||||
|
||||
switch (m_mem_type) {
|
||||
case TensorType::BT_BUF_INTERNAL:
|
||||
case TensorType::BT_BUF_SHARED:
|
||||
m_properties = {
|
||||
ov::intel_gpu::shared_mem_type(ov::intel_gpu::SharedMemType::OCL_BUFFER),
|
||||
ov::intel_gpu::ocl_context(params.context),
|
||||
ov::intel_gpu::mem_handle(params.mem),
|
||||
};
|
||||
break;
|
||||
case TensorType::BT_USM_SHARED:
|
||||
m_properties = {
|
||||
ov::intel_gpu::shared_mem_type(ov::intel_gpu::SharedMemType::USM_USER_BUFFER),
|
||||
ov::intel_gpu::ocl_context(params.context),
|
||||
ov::intel_gpu::mem_handle(params.mem),
|
||||
};
|
||||
break;
|
||||
case TensorType::BT_USM_HOST_INTERNAL:
|
||||
m_properties = {
|
||||
ov::intel_gpu::shared_mem_type(ov::intel_gpu::SharedMemType::USM_HOST_BUFFER),
|
||||
ov::intel_gpu::ocl_context(params.context),
|
||||
ov::intel_gpu::mem_handle(params.mem),
|
||||
};
|
||||
break;
|
||||
case TensorType::BT_USM_DEVICE_INTERNAL:
|
||||
m_properties = {
|
||||
ov::intel_gpu::shared_mem_type(ov::intel_gpu::SharedMemType::USM_DEVICE_BUFFER),
|
||||
ov::intel_gpu::ocl_context(params.context),
|
||||
ov::intel_gpu::mem_handle(params.mem),
|
||||
};
|
||||
break;
|
||||
|
||||
#ifdef _WIN32
|
||||
case TensorType::BT_DX_BUF_SHARED:
|
||||
m_properties = {
|
||||
ov::intel_gpu::shared_mem_type(ov::intel_gpu::SharedMemType::DX_BUFFER),
|
||||
ov::intel_gpu::ocl_context(params.context),
|
||||
ov::intel_gpu::va_device(params.user_device),
|
||||
ov::intel_gpu::mem_handle(params.mem),
|
||||
ov::intel_gpu::dev_object_handle(params.surface),
|
||||
};
|
||||
break;
|
||||
#endif
|
||||
case TensorType::BT_IMG_SHARED:
|
||||
m_properties = {
|
||||
ov::intel_gpu::shared_mem_type(ov::intel_gpu::SharedMemType::OCL_IMAGE2D),
|
||||
ov::intel_gpu::ocl_context(params.context),
|
||||
ov::intel_gpu::mem_handle(params.mem),
|
||||
};
|
||||
break;
|
||||
case TensorType::BT_SURF_SHARED:
|
||||
m_properties = {
|
||||
ov::intel_gpu::shared_mem_type(ov::intel_gpu::SharedMemType::VA_SURFACE),
|
||||
ov::intel_gpu::ocl_context(params.context),
|
||||
ov::intel_gpu::va_device(params.user_device),
|
||||
ov::intel_gpu::mem_handle(params.mem),
|
||||
ov::intel_gpu::dev_object_handle(params.surface),
|
||||
ov::intel_gpu::va_plane(params.plane),
|
||||
};
|
||||
break;
|
||||
default:
|
||||
OPENVINO_THROW("[GPU] Unsupported shared object type ", static_cast<int>(m_mem_type));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
@@ -0,0 +1,815 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "openvino/runtime/make_tensor.hpp"
|
||||
#include "openvino/core/preprocess/input_tensor_info.hpp"
|
||||
#include "openvino/core/parallel.hpp"
|
||||
#include "openvino/op/util/op_types.hpp"
|
||||
#include "transformations/utils/utils.hpp"
|
||||
|
||||
#include "intel_gpu/plugin/sync_infer_request.hpp"
|
||||
#include "intel_gpu/plugin/remote_context.hpp"
|
||||
#include "intel_gpu/plugin/remote_allocators.hpp"
|
||||
#include "intel_gpu/plugin/remote_tensor.hpp"
|
||||
#include "intel_gpu/plugin/compiled_model.hpp"
|
||||
#include "intel_gpu/plugin/variable_state.hpp"
|
||||
#include "intel_gpu/runtime/internal_properties.hpp"
|
||||
#include "intel_gpu/runtime/itt.hpp"
|
||||
#include "intel_gpu/runtime/debug_configuration.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
namespace {
|
||||
|
||||
inline std::string get_port_name(const ov::Output<const ov::Node>& port, const bool is_legacy_api) {
|
||||
std::string name;
|
||||
// TODO: Should use tensor name as the port name, but many legacy tests still use legacy name
|
||||
// plus sometimes it will get empty tensor name.
|
||||
if (!is_legacy_api) {
|
||||
name = {};
|
||||
}
|
||||
if (name.empty()) {
|
||||
bool is_input = ov::op::util::is_parameter(port.get_node());
|
||||
if (is_input) {
|
||||
name = ov::op::util::get_ie_output_name(port);
|
||||
} else {
|
||||
const auto node = port.get_node_shared_ptr();
|
||||
name = ov::op::util::get_ie_output_name(node->input_value(0));
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
template <typename src_t, typename dst_t>
|
||||
void convert_any_copy(const src_t* src, dst_t* dst, size_t size) {
|
||||
OPENVINO_ASSERT(src && dst, "[GPU] Src or Dst ptr is null");
|
||||
for (size_t i = 0; i < size; i++)
|
||||
dst[i] = static_cast<dst_t>(src[i]);
|
||||
}
|
||||
|
||||
void convert_and_copy(const void* src_ptr, ov::element::Type src_et, void* dst_ptr, ov::element::Type dst_et, size_t size) {
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
if (src_et == dst_et) {
|
||||
std::memcpy(dst_ptr, src_ptr, size);
|
||||
return;
|
||||
}
|
||||
|
||||
#define CASE(s_et, d_et, s_type, d_type) \
|
||||
if (src_et == s_et && dst_et == d_et) return convert_any_copy(static_cast<const s_type*>(src_ptr), static_cast<d_type*>(dst_ptr), size)
|
||||
|
||||
// For unsupported inputs
|
||||
CASE(ov::element::f64, ov::element::f32, double, float);
|
||||
CASE(ov::element::i16, ov::element::f32, int16_t, float);
|
||||
CASE(ov::element::u16, ov::element::f32, uint16_t, float);
|
||||
CASE(ov::element::u64, ov::element::i32, uint64_t, int32_t);
|
||||
CASE(ov::element::i64, ov::element::i32, int64_t, int32_t);
|
||||
CASE(ov::element::u32, ov::element::i32, uint32_t, int32_t);
|
||||
|
||||
// For unsupported outputs
|
||||
CASE(ov::element::f32, ov::element::f64, float, double);
|
||||
CASE(ov::element::i32, ov::element::i64, int32_t, int64_t);
|
||||
CASE(ov::element::i32, ov::element::u64, int32_t, uint64_t);
|
||||
CASE(ov::element::i32, ov::element::u32, int32_t, uint32_t);
|
||||
CASE(ov::element::f32, ov::element::i16, float, int16_t);
|
||||
CASE(ov::element::f32, ov::element::u16, float, uint16_t);
|
||||
|
||||
// TODO: Need instances below?
|
||||
CASE(ov::element::u32, ov::element::i64, uint32_t, int64_t);
|
||||
CASE(ov::element::u32, ov::element::u64, uint32_t, uint64_t);
|
||||
|
||||
OPENVINO_THROW("[GPU] Unsupported element types combination for copy: ", src_et, " -> ", dst_et);
|
||||
}
|
||||
|
||||
bool is_convert_required(ov::element::Type src_et, ov::element::Type dst_et) {
|
||||
return src_et != dst_et && !(dst_et == ov::element::boolean && src_et == ov::element::u8);
|
||||
}
|
||||
|
||||
void convert_and_copy(const cldnn::memory::ptr src, ov::ITensor const* dst, const cldnn::stream& stream) {
|
||||
auto src_et = cldnn::data_type_to_element_type(src->get_layout().data_type);
|
||||
auto dst_et = dst->get_element_type();
|
||||
|
||||
size_t size = ov::shape_size(dst->get_shape());
|
||||
|
||||
cldnn::mem_lock<uint8_t> src_lock(src, stream);
|
||||
std::unique_ptr<cldnn::mem_lock<uint8_t>> dst_lock = nullptr;
|
||||
|
||||
const void* src_ptr = src_lock.data();
|
||||
void* dst_ptr = nullptr;
|
||||
|
||||
if (auto remote = dynamic_cast<const ov::intel_gpu::RemoteTensorImpl*>(dst)) {
|
||||
auto mem = remote->get_original_memory();
|
||||
dst_lock.reset(new cldnn::mem_lock<uint8_t>(mem, stream));
|
||||
dst_ptr = dst_lock->data();
|
||||
} else {
|
||||
dst_ptr = dst->data();
|
||||
}
|
||||
|
||||
return convert_and_copy(src_ptr, src_et, dst_ptr, dst_et, size);
|
||||
}
|
||||
|
||||
void convert_and_copy(const ov::ITensor* src, ov::ITensor const* dst, const cldnn::stream& stream) {
|
||||
auto src_et = src->get_element_type();
|
||||
auto dst_et = dst->get_element_type();
|
||||
|
||||
size_t size = ov::shape_size(dst->get_shape());
|
||||
|
||||
const void* src_ptr = nullptr;
|
||||
void* dst_ptr = nullptr;
|
||||
|
||||
std::unique_ptr<cldnn::mem_lock<uint8_t>> src_lock = nullptr;
|
||||
std::unique_ptr<cldnn::mem_lock<uint8_t>> dst_lock = nullptr;
|
||||
|
||||
if (auto remote = dynamic_cast<const ov::intel_gpu::RemoteTensorImpl*>(src)) {
|
||||
auto mem = remote->get_original_memory();
|
||||
src_lock.reset(new cldnn::mem_lock<uint8_t>(mem, stream));
|
||||
src_ptr = src_lock->data();
|
||||
} else {
|
||||
src_ptr = src->data();
|
||||
}
|
||||
|
||||
if (auto remote = dynamic_cast<const ov::intel_gpu::RemoteTensorImpl*>(dst)) {
|
||||
auto mem = remote->get_original_memory();
|
||||
dst_lock.reset(new cldnn::mem_lock<uint8_t>(mem, stream));
|
||||
dst_ptr = dst_lock->data();
|
||||
} else {
|
||||
dst_ptr = dst->data();
|
||||
}
|
||||
|
||||
return convert_and_copy(src_ptr, src_et, dst_ptr, dst_et, size);
|
||||
}
|
||||
|
||||
bool same_host_mem(cldnn::memory::cptr memory, const uint8_t* host_ptr) {
|
||||
const uint8_t* device_ptr = memory->get_allocation_type() == cldnn::allocation_type::usm_host ?
|
||||
static_cast<uint8_t*>(memory->get_internal_params().mem) : nullptr;
|
||||
return device_ptr == host_ptr;
|
||||
}
|
||||
|
||||
ov::Shape predict_shape(const std::string& name, const ov::Shape current_shape, ov::element::Type element_type, cldnn::ShapePredictor& shape_predictor) {
|
||||
auto et_size = cldnn::ceil_div(element_type.bitwidth(), 8);
|
||||
auto prealloc_info = shape_predictor.predict_preallocation_shape(name, current_shape, et_size, false);
|
||||
const auto& preallocation_shape = prealloc_info.second;
|
||||
auto can_preallocate_buffer = prealloc_info.first &&
|
||||
shape_predictor.can_preallocate(ov::shape_size(preallocation_shape) * et_size);
|
||||
if (can_preallocate_buffer) {
|
||||
return preallocation_shape;
|
||||
}
|
||||
|
||||
return current_shape;
|
||||
}
|
||||
|
||||
inline bool all_remote_buffers(const std::vector<ov::SoPtr<ov::ITensor>>& tensors) {
|
||||
return std::all_of(tensors.begin(), tensors.end(), [](const ov::SoPtr<ov::ITensor>& tensor) {
|
||||
if (auto remote_ptr = std::dynamic_pointer_cast<ov::intel_gpu::RemoteTensorImpl>(tensor._ptr)) {
|
||||
return !remote_ptr->is_surface();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
inline bool all_remote_surfaces(const std::vector<ov::SoPtr<ov::ITensor>>& tensors) {
|
||||
return std::all_of(tensors.begin(), tensors.end(), [](const ov::SoPtr<ov::ITensor>& tensor) {
|
||||
if (auto remote_ptr = std::dynamic_pointer_cast<ov::intel_gpu::RemoteTensorImpl>(tensor._ptr)) {
|
||||
return remote_ptr->is_surface();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
inline bool all_host_tensors(const std::vector<ov::SoPtr<ov::ITensor>>& tensors) {
|
||||
return std::all_of(tensors.begin(), tensors.end(), [](const ov::SoPtr<ov::ITensor>& tensor) {
|
||||
return std::dynamic_pointer_cast<ov::intel_gpu::RemoteTensorImpl>(tensor._ptr) == nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
// ----------------------------------------------------------------------------------------------- //
|
||||
// ---------------------------- OpenVINO API impl ------------------------------------------------ //
|
||||
// ----------------------------------------------------------------------------------------------- //
|
||||
|
||||
SyncInferRequest::SyncInferRequest(const std::shared_ptr<const CompiledModel>& compiled_model)
|
||||
: ov::ISyncInferRequest(compiled_model)
|
||||
, m_graph(compiled_model->get_graph(0))
|
||||
, m_context(std::static_pointer_cast<RemoteContextImpl>(compiled_model->get_context_impl()))
|
||||
, m_enable_profiling(m_graph->get_config().get_property(ov::enable_profiling))
|
||||
, m_use_external_queue(m_graph->use_external_queue()) {
|
||||
bool is_legacy_api = !compiled_model->is_new_api();
|
||||
init_mappings(is_legacy_api);
|
||||
allocate_inputs();
|
||||
allocate_outputs();
|
||||
allocate_states();
|
||||
}
|
||||
|
||||
void SyncInferRequest::infer() {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "SyncInferRequest::infer");
|
||||
setup_stream_graph();
|
||||
std::lock_guard<std::mutex> lk(m_graph->get_mutex());
|
||||
enqueue();
|
||||
wait();
|
||||
}
|
||||
|
||||
std::vector<ov::ProfilingInfo> SyncInferRequest::get_profiling_info() const {
|
||||
OPENVINO_ASSERT(m_enable_profiling, "[GPU] Profiling data was not collected: please check that ov::enable_profiling property was set to true");
|
||||
return m_graph->get_profiling_info();
|
||||
}
|
||||
|
||||
std::vector<ov::SoPtr<ov::IVariableState>> SyncInferRequest::query_state() const {
|
||||
std::vector<ov::SoPtr<ov::IVariableState>> ret{};
|
||||
const auto& variable_states = m_graph->get_network()->get_variable_memories();
|
||||
for (const auto& pair : variable_states) {
|
||||
ret.emplace_back(std::make_shared<VariableState>(pair.first, pair.second, m_graph->get_engine()));
|
||||
}
|
||||
auto expected_states_count = m_graph->get_network()->get_variables_state_info().size();
|
||||
OPENVINO_ASSERT(expected_states_count == ret.size(), "[GPU] Mismatch of expected states count (",
|
||||
expected_states_count, ") and actual size (", ret.size(), ")");
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SyncInferRequest::set_tensor(const ov::Output<const ov::Node>& port, const ov::SoPtr<ov::ITensor>& tensor) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "SyncInferRequest::set_tensor");
|
||||
const auto& compiled_model = std::static_pointer_cast<const CompiledModel>(get_compiled_model());
|
||||
const auto name = get_port_name(port, !compiled_model->is_new_api());
|
||||
const auto& shape = port.get_partial_shape();
|
||||
|
||||
OPENVINO_ASSERT(tensor != nullptr, "[GPU] Failed to set empty tensor to port: \'", name, "\'");
|
||||
OPENVINO_ASSERT(port.get_element_type() == tensor->get_element_type(),
|
||||
"[GPU] Mismtach tensor and port type: ", port.get_element_type(), " vs ", tensor->get_element_type());
|
||||
OPENVINO_ASSERT(shape.compatible(ov::PartialShape(tensor->get_shape())) || tensor->get_shape() == ov::Shape{0},
|
||||
"[GPU] The tensor size is not equal to model, can't set input tensor with name: ",
|
||||
name,
|
||||
", because model input (shape=",
|
||||
shape,
|
||||
") and tensor (shape=",
|
||||
tensor->get_shape(),
|
||||
") are incompatible");
|
||||
|
||||
bool is_input = ov::op::util::is_parameter(port.get_node());
|
||||
|
||||
if (is_input) {
|
||||
m_user_inputs[name] = { tensor._ptr, TensorOwner::USER };
|
||||
} else {
|
||||
m_user_outputs[name] = { tensor._ptr, TensorOwner::USER };
|
||||
}
|
||||
|
||||
ov::ISyncInferRequest::set_tensor(port, tensor);
|
||||
}
|
||||
|
||||
void SyncInferRequest::set_tensors_impl(const ov::Output<const ov::Node> port, const std::vector<ov::SoPtr<ov::ITensor>>& tensors) {
|
||||
if (tensors.size() == 1) {
|
||||
return set_tensor(port, tensors[0]);
|
||||
}
|
||||
bool is_input = ov::op::util::is_parameter(port.get_node());
|
||||
OPENVINO_ASSERT(is_input, "[GPU] set_tensors_impl is not supported for output port");
|
||||
|
||||
bool is_remote = all_remote_buffers(tensors) || all_remote_surfaces(tensors);
|
||||
bool is_host = all_host_tensors(tensors);
|
||||
|
||||
OPENVINO_ASSERT(is_host || is_remote, "[GPU] Incorrect input blobs. All blobs must be of the same type");
|
||||
|
||||
for (const auto& input : get_inputs()) {
|
||||
if (input == port) {
|
||||
m_batched_tensors[input.get_tensor_ptr()] = tensors;
|
||||
return;
|
||||
}
|
||||
}
|
||||
OPENVINO_THROW("[GPU] Cannot find input tensors for port ", port);
|
||||
}
|
||||
|
||||
ov::SoPtr<ov::ITensor> SyncInferRequest::get_tensor(const ov::Output<const ov::Node>& port) const {
|
||||
bool is_input = ov::op::util::is_parameter(port.get_node());
|
||||
const auto& compiled_model = std::static_pointer_cast<const CompiledModel>(get_compiled_model());
|
||||
const auto name = get_port_name(port, !compiled_model->is_new_api());
|
||||
if (is_input) {
|
||||
OPENVINO_ASSERT(m_user_inputs.count(name) == 1, "[GPU] Input tensor with name ", name, " is not found");
|
||||
return { m_user_inputs.at(name).ptr, nullptr };
|
||||
} else {
|
||||
OPENVINO_ASSERT(m_user_outputs.count(name) == 1, "[GPU] Output tensor with name ", name, " is not found");
|
||||
return { m_user_outputs.at(name).ptr, nullptr };
|
||||
}
|
||||
}
|
||||
|
||||
void SyncInferRequest::check_tensors() const {
|
||||
const auto& inputs = get_compiled_model()->inputs();
|
||||
for (size_t i = 0; i < inputs.size(); i++) {
|
||||
if (!is_batched_input(inputs[i]))
|
||||
check_tensor(inputs[i], get_tensor_ptr(inputs[i]));
|
||||
}
|
||||
const auto& outputs = get_compiled_model()->outputs();
|
||||
for (size_t i = 0; i < outputs.size(); i++) {
|
||||
check_tensor(outputs[i], get_tensor_ptr(outputs[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------- //
|
||||
// ---------------------------- internal pipeline stages ----------------------------------- //
|
||||
// ----------------------------------------------------------------------------------------- //
|
||||
void SyncInferRequest::set_task_executor(const std::shared_ptr<ov::threading::ITaskExecutor>& task_executor) {
|
||||
m_stream_executor = std::dynamic_pointer_cast<ov::threading::IStreamsExecutor>(task_executor);
|
||||
}
|
||||
|
||||
void SyncInferRequest::enqueue_notify() {
|
||||
m_graph->wait(Graph::Stage::EXECUTE);
|
||||
enqueue();
|
||||
}
|
||||
|
||||
void SyncInferRequest::wait_notify() {
|
||||
wait();
|
||||
m_graph->notify(Graph::Stage::EXECUTE);
|
||||
}
|
||||
|
||||
void SyncInferRequest::enqueue() {
|
||||
// set input and output memory from request blob maps
|
||||
// into the network object primitives
|
||||
std::vector<cldnn::event::ptr> dependencies;
|
||||
|
||||
for (const auto& it : m_input_ports_map) {
|
||||
const auto& name = it.first;
|
||||
const auto& port = it.second;
|
||||
|
||||
if (m_batched_tensors.count(port.get_tensor_ptr()) > 0) {
|
||||
auto events = prepare_batched_input(name, port, m_batched_tensors.at(port.get_tensor_ptr()));
|
||||
std::move(events.begin(), events.end(), std::back_inserter(dependencies));
|
||||
} else {
|
||||
auto events = prepare_input(name, port, m_user_inputs.at(name));
|
||||
std::move(events.begin(), events.end(), std::back_inserter(dependencies));
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& it : m_output_ports_map) {
|
||||
const auto& name = it.first;
|
||||
const auto& port = it.second;
|
||||
|
||||
auto events = prepare_output(name, port, m_user_outputs.at(name));
|
||||
std::move(events.begin(), events.end(), std::back_inserter(dependencies));
|
||||
}
|
||||
|
||||
auto network = m_graph->get_network();
|
||||
network->assign_variables_memories();
|
||||
|
||||
m_internal_outputs.clear();
|
||||
m_internal_outputs = network->execute(dependencies);
|
||||
|
||||
// If dump layers path is set, only runs first inference.
|
||||
GPU_DEBUG_GET_INSTANCE(debug_config);
|
||||
GPU_DEBUG_IF(debug_config->dump_layers_path.length() > 0 && debug_config->dump_iteration.empty()) {
|
||||
GPU_DEBUG_INFO << "Only run first inference to dump layers." << std::endl;
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void SyncInferRequest::wait() {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "SyncInferRequest::wait");
|
||||
OPENVINO_ASSERT(!m_internal_outputs.empty(), "[GPU] Inference was not started!\n");
|
||||
|
||||
// wait for completion & collect outputs as requested by the model
|
||||
// for in_order_queue, it is enough to call finish only once
|
||||
bool do_sync_per_output = (m_graph->get_network()->get_stream().get_queue_type() == QueueTypes::in_order) ? false : true;
|
||||
if (!do_sync_per_output)
|
||||
m_graph->get_network()->get_stream().finish();
|
||||
|
||||
std::vector<cldnn::event::ptr> copy_events;
|
||||
|
||||
for (const auto& it : m_output_ports_map) {
|
||||
const auto& name = it.first;
|
||||
const auto& port = it.second;
|
||||
cldnn::primitive_id internal_name = m_output_names_map.at(name);
|
||||
auto output_memory = m_internal_outputs.at(internal_name).get_memory(do_sync_per_output);
|
||||
auto output_layout = m_internal_outputs.at(internal_name).get_layout();
|
||||
|
||||
if (output_memory) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "SyncInferRequest::wait::reinterpret_memory");
|
||||
OPENVINO_ASSERT(!output_memory->get_layout().data_padding, "[GPU] Unexpected padding in output buffer");
|
||||
output_memory = m_graph->get_engine().reinterpret_buffer(*output_memory, output_layout);
|
||||
}
|
||||
|
||||
OPENVINO_ASSERT(m_user_outputs.count(name) > 0, "[GPU] Output ", name, " is not found in output tensors map");
|
||||
auto output_tensor_wrapper = m_user_outputs.at(name);
|
||||
auto output_tensor = output_tensor_wrapper.ptr;
|
||||
auto remote_ptr = std::dynamic_pointer_cast<RemoteTensorImpl>(output_tensor);
|
||||
bool is_remote = remote_ptr != nullptr;
|
||||
|
||||
bool need_output_update = output_layout.bytes_count() == 0 || (output_memory && output_tensor->get_byte_size() != output_memory->size());
|
||||
if (need_output_update) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "SyncInferRequest::wait::update_output");
|
||||
auto mem_shape = output_layout.get_shape();
|
||||
// In case of old shape infer we need to shrink out tensor shape to avoid redudnant dimensions that occur due to rank extension
|
||||
// For new shape infer this shouldn't happen, thus remove that WA once we migrate to ngraph-based shape infer for all cases
|
||||
if (!m_graph->get_config().get_property(ov::intel_gpu::allow_new_shape_infer)) {
|
||||
OPENVINO_ASSERT(port.get_partial_shape().is_static(), "[GPU] Unexpected dynamic shape for legacy shape inference");
|
||||
OPENVINO_ASSERT(ov::shape_size(port.get_shape()) == ov::shape_size(mem_shape), "[GPU] Unexpected elements count for output tensor");
|
||||
mem_shape = port.get_shape();
|
||||
}
|
||||
output_tensor->set_shape(mem_shape);
|
||||
}
|
||||
|
||||
// mapping remote blobs not needed -
|
||||
// let the user take care of them explicitly
|
||||
if (!is_remote && output_memory) {
|
||||
auto dst_ptr = static_cast<uint8_t*>(output_tensor->data());
|
||||
bool same_mem = same_host_mem(output_memory, dst_ptr);
|
||||
if (!same_mem && output_memory->size()) {
|
||||
if (auto ev = copy_output_data(output_memory, *output_tensor)) {
|
||||
copy_events.push_back(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!copy_events.empty()) {
|
||||
auto& stream = m_graph->get_network()->get_stream();
|
||||
if (stream.get_queue_type() == QueueTypes::in_order) {
|
||||
// wait only the last one
|
||||
stream.wait_for_events({copy_events.back()});
|
||||
} else {
|
||||
stream.wait_for_events(copy_events);
|
||||
}
|
||||
}
|
||||
|
||||
// finally collect profiling info
|
||||
if (m_enable_profiling) {
|
||||
m_graph->update_profiling_info();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------- //
|
||||
// ---------------------------- internal utils --------- ----------------------------------- //
|
||||
// ----------------------------------------------------------------------------------------- //
|
||||
void SyncInferRequest::setup_stream_graph() {
|
||||
int stream_id = 0;
|
||||
auto& stream_graphs = std::static_pointer_cast<const CompiledModel>(get_compiled_model())->get_graphs();
|
||||
if (nullptr != m_stream_executor) {
|
||||
stream_id = m_stream_executor->get_stream_id();
|
||||
auto num_graphs = stream_graphs.size();
|
||||
stream_id = stream_id % num_graphs;
|
||||
}
|
||||
m_graph = stream_graphs[stream_id];
|
||||
}
|
||||
|
||||
std::shared_ptr<ov::ITensor> SyncInferRequest::create_host_tensor(const ov::PartialShape& port_shape, const ov::element::Type& port_element_type) const {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "SyncInferRequest::create_host_tensor");
|
||||
// Disable USM usage as USMHostAllocator may fail for attempt to allocate 0 bytes
|
||||
// If we add WA for such case to avoid driver call, then deallocate method will return false and Blob::setShape call will throw an exception
|
||||
bool use_usm = m_graph->get_engine().use_unified_shared_memory() && !port_shape.is_dynamic();
|
||||
|
||||
auto shape = port_shape.is_static() ? port_shape.to_shape() : ov::Shape(port_shape.size(), 0);
|
||||
auto usm_allocator = USMHostAllocator(m_context);
|
||||
return use_usm ? ov::make_tensor(port_element_type, shape, usm_allocator)
|
||||
: ov::make_tensor(port_element_type, shape);
|
||||
}
|
||||
|
||||
std::shared_ptr<ov::ITensor> SyncInferRequest::create_device_tensor(const ov::Shape& shape, ov::element::Type element_type,
|
||||
bool need_lockable_memory, void* mem_ptr) const {
|
||||
TensorType tensor_type = TensorType::BT_EMPTY;
|
||||
if (mem_ptr) {
|
||||
tensor_type = TensorType::BT_USM_SHARED;
|
||||
} else if (m_graph->get_engine().use_unified_shared_memory()) {
|
||||
tensor_type = need_lockable_memory ? TensorType::BT_USM_HOST_INTERNAL : TensorType::BT_USM_DEVICE_INTERNAL;
|
||||
} else {
|
||||
tensor_type = TensorType::BT_BUF_INTERNAL;
|
||||
}
|
||||
|
||||
// Currently, clDeviceMemAllocINTEL returns memory address allocated to other input blob if the current blob is empty
|
||||
// W/A for this issue:
|
||||
// Allocate with non-empty shape and then reinterprete with original shape
|
||||
auto shape_copy = shape;
|
||||
for (auto &i : shape_copy) {
|
||||
if (i == 0)
|
||||
i = 1;
|
||||
}
|
||||
|
||||
return std::make_shared<RemoteTensorImpl>(m_context,
|
||||
shape_copy,
|
||||
element_type,
|
||||
tensor_type,
|
||||
mem_ptr);
|
||||
}
|
||||
|
||||
std::shared_ptr<ov::ITensor> SyncInferRequest::create_shared_device_tensor(const ov::Shape& shape, ov::element::Type element_type, void* usm_host_mem) const {
|
||||
return create_device_tensor(shape, element_type, false, usm_host_mem);
|
||||
}
|
||||
|
||||
TensorWrapper SyncInferRequest::create_or_share_device_tensor(const TensorWrapper& user_tensor_wrapper,
|
||||
const std::string& name,
|
||||
const ov::PartialShape& port_pshape,
|
||||
ov::element::Type element_type,
|
||||
bool need_lockable_mem) const {
|
||||
auto user_tensor = user_tensor_wrapper.ptr;
|
||||
auto tensor_shape = user_tensor->get_shape();
|
||||
bool is_dynamic = port_pshape.is_dynamic();
|
||||
OPENVINO_ASSERT(std::dynamic_pointer_cast<RemoteTensorImpl>(user_tensor) == nullptr, "[GPU] Unexpected remote tensor");
|
||||
auto input_ptr = user_tensor->data();
|
||||
const auto alloc_type = m_graph->get_engine().detect_usm_allocation_type(input_ptr);
|
||||
const auto is_usm_host = alloc_type == cldnn::allocation_type::usm_host;
|
||||
bool can_share = is_usm_host && !is_convert_required(user_tensor->get_element_type(), element_type);
|
||||
|
||||
if (can_share) {
|
||||
// For USM case we create host blob using custom USM host allocator
|
||||
// and then create shared device blob on top of this buffer
|
||||
return { create_shared_device_tensor(tensor_shape, element_type, input_ptr), user_tensor_wrapper.owner };
|
||||
}
|
||||
|
||||
auto actual_memory_shape = tensor_shape;
|
||||
if (is_dynamic) {
|
||||
auto& shape_predictor = m_graph->get_network()->get_shape_predictor();
|
||||
actual_memory_shape = predict_shape(name, tensor_shape, element_type, shape_predictor);
|
||||
}
|
||||
|
||||
return { create_device_tensor(actual_memory_shape, element_type, need_lockable_mem), TensorOwner::PLUGIN };
|
||||
}
|
||||
|
||||
cldnn::event::ptr SyncInferRequest::copy_output_data(cldnn::memory::ptr src, const ov::ITensor& dst) const {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "SyncInferRequest::copy_output_data");
|
||||
OPENVINO_ASSERT(src->count() <= dst.get_size(),
|
||||
"[GPU] Unexpected elements count of dst tensor: ",
|
||||
"expected at least ", src->count(), ", but ",
|
||||
"only ", dst.get_size(), " got");
|
||||
|
||||
const auto& layout = src->get_layout();
|
||||
auto& stream = m_graph->get_network()->get_stream();
|
||||
|
||||
if (is_convert_required(cldnn::data_type_to_element_type(layout.data_type), dst.get_element_type())) {
|
||||
convert_and_copy(src, &dst, stream);
|
||||
return nullptr;
|
||||
} else {
|
||||
return src->copy_to(stream, dst.data(), false);
|
||||
}
|
||||
}
|
||||
|
||||
void SyncInferRequest::allocate_input(const ov::Output<const ov::Node>& port, const std::string& name) {
|
||||
const auto& shape = port.get_partial_shape();
|
||||
auto element_type = port.get_element_type();
|
||||
|
||||
m_user_inputs[name] = { create_host_tensor(shape, element_type), TensorOwner::PLUGIN };
|
||||
ov::ISyncInferRequest::set_tensor(port, m_user_inputs.at(name).ptr);
|
||||
}
|
||||
|
||||
void SyncInferRequest::allocate_output(const ov::Output<const ov::Node>& port, const std::string& name) {
|
||||
const auto& shape = port.get_partial_shape();
|
||||
auto element_type = port.get_element_type();
|
||||
|
||||
m_user_outputs[name] = { create_host_tensor(shape, element_type), TensorOwner::PLUGIN };
|
||||
ov::ISyncInferRequest::set_tensor(port, m_user_outputs.at(name).ptr);
|
||||
}
|
||||
|
||||
void SyncInferRequest::allocate_inputs() {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "SyncInferRequest::allocate_inputs");
|
||||
|
||||
for (const auto& it : m_input_ports_map) {
|
||||
const auto& name = it.first;
|
||||
const auto& port = it.second;
|
||||
GPU_DEBUG_LOG << "[init " << name << " input blob]" << std::endl;
|
||||
|
||||
bool is_nv12_input = false;
|
||||
if (port.get_rt_info().count(ov::preprocess::TensorInfoMemoryType::get_type_info_static())) {
|
||||
std::string mem_type = port.get_rt_info().at(ov::preprocess::TensorInfoMemoryType::get_type_info_static())
|
||||
.as<ov::preprocess::TensorInfoMemoryType>().value;
|
||||
if (mem_type.find(ov::intel_gpu::memory_type::surface) != std::string::npos) {
|
||||
is_nv12_input = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_nv12_input) {
|
||||
allocate_input(port, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SyncInferRequest::allocate_outputs() {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "SyncInferRequest::allocate_outputs");
|
||||
|
||||
// allocate outputs
|
||||
for (const auto& it : m_output_ports_map) {
|
||||
const auto& name = it.first;
|
||||
const auto& port = it.second;
|
||||
GPU_DEBUG_LOG << "[init " << name << " output blob]" << std::endl;
|
||||
|
||||
allocate_output(port, name);
|
||||
}
|
||||
}
|
||||
|
||||
void SyncInferRequest::allocate_states() {
|
||||
m_graph->get_network()->allocate_variables_memories();
|
||||
}
|
||||
|
||||
std::vector<cldnn::event::ptr> SyncInferRequest::prepare_batched_input(const std::string& name,
|
||||
const ov::Output<const ov::Node>& port,
|
||||
const std::vector<ov::SoPtr<ov::ITensor>>& user_tensors) {
|
||||
std::vector<cldnn::event::ptr> ret_events;
|
||||
bool is_host = all_host_tensors(user_tensors);
|
||||
bool is_remote_buffer = all_remote_buffers(user_tensors);
|
||||
// Host buffers are merged to single tensor
|
||||
if (is_host || is_remote_buffer) {
|
||||
auto tmp_shape = user_tensors.at(0)->get_shape();
|
||||
auto tmp_et = user_tensors.at(0)->get_element_type();
|
||||
tmp_shape[0] = user_tensors.size();
|
||||
std::shared_ptr<ov::ITensor> merged_tensor = nullptr;
|
||||
if (is_host) {
|
||||
merged_tensor = m_context->create_host_tensor(tmp_et, tmp_shape)._ptr;
|
||||
auto ptr = static_cast<uint8_t*>(merged_tensor->data());
|
||||
ov::parallel_for(user_tensors.size(), [&](size_t i) {
|
||||
const auto& tensor = user_tensors.at(i);
|
||||
std::memcpy(ptr + i * tensor->get_byte_size(), static_cast<uint8_t*>(tensor->data()), tensor->get_byte_size());
|
||||
});
|
||||
} else {
|
||||
const auto& stream = m_graph->get_network()->get_stream();
|
||||
merged_tensor = m_context->create_tensor(tmp_et, tmp_shape, {})._ptr;
|
||||
auto merged_memory = std::dynamic_pointer_cast<RemoteTensorImpl>(merged_tensor)->get_memory();
|
||||
cldnn::mem_lock<uint8_t> dst_lock(merged_memory, stream);
|
||||
for (size_t i = 0; i < user_tensors.size(); i++) {
|
||||
auto input_tensor = std::dynamic_pointer_cast<RemoteTensorImpl>(user_tensors[i]._ptr);
|
||||
cldnn::mem_lock<uint8_t> src_lock(input_tensor->get_memory(), stream);
|
||||
std::memcpy(dst_lock.data() + i * input_tensor->get_byte_size(), src_lock.data(), input_tensor->get_byte_size());
|
||||
}
|
||||
}
|
||||
|
||||
auto events = prepare_input(name, port, {merged_tensor, TensorOwner::PLUGIN});
|
||||
std::move(events.begin(), events.end(), std::back_inserter(ret_events));
|
||||
} else {
|
||||
for (size_t i = 0; i < user_tensors.size(); i++) {
|
||||
auto new_name = name + "_" + std::to_string(i);
|
||||
auto events = prepare_input(new_name, port, {user_tensors[i]._ptr, TensorOwner::USER});
|
||||
std::move(events.begin(), events.end(), std::back_inserter(ret_events));
|
||||
}
|
||||
}
|
||||
|
||||
return ret_events;
|
||||
}
|
||||
|
||||
std::vector<cldnn::event::ptr> SyncInferRequest::prepare_input(const std::string& name,
|
||||
const ov::Output<const ov::Node>& port,
|
||||
const TensorWrapper& user_tensor_wrapper) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "SyncInferRequest::prepare_input");
|
||||
auto pshape = port.get_partial_shape();
|
||||
auto is_dynamic = pshape.is_dynamic();
|
||||
auto user_tensor = user_tensor_wrapper.ptr;
|
||||
auto element_type = user_tensor->get_element_type();
|
||||
auto remote_ptr = std::dynamic_pointer_cast<RemoteTensorImpl>(user_tensor);
|
||||
bool is_remote = remote_ptr != nullptr;
|
||||
|
||||
auto network = m_graph->get_network();
|
||||
auto& engine = m_graph->get_engine();
|
||||
auto& stream = network->get_stream();
|
||||
|
||||
OPENVINO_ASSERT(pshape.compatible(ov::PartialShape(user_tensor->get_shape())) || is_batched_input(port),
|
||||
"[GPU] The input tensor size is not equal to model port shape, can't handle input tensor with name: ",
|
||||
name,
|
||||
", because model input (shape=",
|
||||
pshape,
|
||||
") and tensor (shape=",
|
||||
user_tensor->get_shape(),
|
||||
") are incompatible");
|
||||
|
||||
if (is_remote) {
|
||||
m_plugin_inputs[name] = user_tensor_wrapper;
|
||||
}
|
||||
|
||||
auto device_tensor_et = convert_to_supported_device_type(element_type);
|
||||
bool convert_needed = is_convert_required(element_type, device_tensor_et);
|
||||
bool update_device_tensor = m_plugin_inputs.count(name) == 0 || (m_plugin_inputs[name].owner == TensorOwner::USER && !is_remote);
|
||||
|
||||
if (update_device_tensor) {
|
||||
// If device input hasn't been created, then try to use user memory if it's usm_host, or allocate new device buffer
|
||||
m_plugin_inputs[name] = create_or_share_device_tensor(user_tensor_wrapper, name, pshape, device_tensor_et, convert_needed);
|
||||
} else if (!is_remote) {
|
||||
// Device memory has been created on previous iterations. Try to reuse whenever it's possible
|
||||
auto device_tensor_wrapper = m_plugin_inputs.at(name);
|
||||
auto device_tensor = std::dynamic_pointer_cast<RemoteTensorImpl>(device_tensor_wrapper.ptr);
|
||||
if (is_dynamic) {
|
||||
if (device_tensor->get_original_memory()->size() < user_tensor->get_byte_size()) {
|
||||
auto& shape_predictor = network->get_shape_predictor();
|
||||
auto actual_shape = predict_shape(name, user_tensor->get_shape(), device_tensor_et, shape_predictor);
|
||||
auto new_tensor = create_device_tensor(actual_shape, device_tensor_et, false);
|
||||
new_tensor->set_shape(user_tensor->get_shape());
|
||||
m_plugin_inputs[name] = { new_tensor, TensorOwner::PLUGIN };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto device_tensor = std::dynamic_pointer_cast<RemoteTensorImpl>(m_plugin_inputs.at(name).ptr);
|
||||
if (is_dynamic) {
|
||||
OPENVINO_ASSERT(device_tensor->get_original_memory()->size() >= user_tensor->get_size(),
|
||||
"[GPU] Size of input device tensor (=",
|
||||
device_tensor->get_original_memory()->size(),
|
||||
") is expected to be greater or equal to user tensor (=",
|
||||
user_tensor->get_size(),
|
||||
") in dynamic case for ", name);
|
||||
// tensor reshape below is expected to work w/o reallocation
|
||||
device_tensor->set_shape(user_tensor->get_shape());
|
||||
} else {
|
||||
OPENVINO_ASSERT(device_tensor->get_size() == user_tensor->get_size(),
|
||||
"[GPU] Size of user tensor (=",
|
||||
user_tensor->get_size(),
|
||||
") and device tensor (=",
|
||||
device_tensor->get_size(),
|
||||
") don't match for ", name,
|
||||
". Those are expected to be equal in case of static shape of the port");
|
||||
}
|
||||
|
||||
auto memory = device_tensor->get_memory();
|
||||
// WA to extend shape to ranks expected by legacy shape infer. Remove after full migration to new shape infer
|
||||
if (!m_graph->get_config().get_property(ov::intel_gpu::allow_new_shape_infer)) {
|
||||
auto new_layout = memory->get_layout();
|
||||
new_layout.set_partial_shape(m_graph->get_input_layouts().at(name).get_shape());
|
||||
memory = engine.reinterpret_buffer(*memory, new_layout);
|
||||
}
|
||||
|
||||
cldnn::event::ptr ret_event = nullptr;
|
||||
if (!is_remote) {
|
||||
if (device_tensor->get_element_type() != user_tensor->get_element_type()) {
|
||||
convert_and_copy(user_tensor.get(), device_tensor.get(), stream);
|
||||
} else {
|
||||
auto src_ptr = static_cast<uint8_t*>(user_tensor->data());
|
||||
if (!same_host_mem(memory, src_ptr)) {
|
||||
ret_event = memory->copy_from(stream, src_ptr, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const cldnn::primitive_id internal_name = "parameter:" + name;
|
||||
network->set_input_data(internal_name, memory);
|
||||
|
||||
if (ret_event)
|
||||
return { ret_event };
|
||||
else
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<cldnn::event::ptr> SyncInferRequest::prepare_output(const std::string& name,
|
||||
const ov::Output<const ov::Node>& port,
|
||||
const TensorWrapper& user_tensor_wrapper) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::intel_gpu_plugin, "SyncInferRequest::prepare_output");
|
||||
auto pshape = port.get_partial_shape();
|
||||
auto is_dynamic = pshape.is_dynamic();
|
||||
auto element_type = port.get_element_type();
|
||||
auto user_tensor = user_tensor_wrapper.ptr;
|
||||
auto remote_ptr = std::dynamic_pointer_cast<RemoteTensorImpl>(user_tensor);
|
||||
bool is_remote = remote_ptr != nullptr;
|
||||
|
||||
if (user_tensor->get_size() > 0) {
|
||||
OPENVINO_ASSERT(pshape.compatible(ov::PartialShape(user_tensor->get_shape())),
|
||||
"[GPU] The output tensor size is not equal to model port shape, can't handle output tensor with name: ",
|
||||
name,
|
||||
", because model output (shape=",
|
||||
pshape,
|
||||
") and tensor (shape=",
|
||||
user_tensor->get_shape(),
|
||||
") are incompatible");
|
||||
}
|
||||
|
||||
auto network = m_graph->get_network();
|
||||
auto device_tensor_et = convert_to_supported_device_type(element_type);
|
||||
bool convert_needed = is_convert_required(device_tensor_et, element_type);
|
||||
cldnn::primitive_id internal_name = m_output_names_map.at(name);
|
||||
if (is_remote && !convert_needed) {
|
||||
m_plugin_outputs[name] = user_tensor_wrapper;
|
||||
}
|
||||
|
||||
if (!is_dynamic) {
|
||||
auto is_cpu_impl = network->is_cpu_impl(internal_name);
|
||||
bool has_device_buffer = m_plugin_outputs.count(name) > 0;
|
||||
bool update_device_tensor = !has_device_buffer ||
|
||||
(m_plugin_outputs[name].owner == TensorOwner::USER && !is_remote);
|
||||
if (update_device_tensor) {
|
||||
m_plugin_outputs[name] = create_or_share_device_tensor(user_tensor_wrapper, name, pshape, device_tensor_et, is_cpu_impl || convert_needed);
|
||||
}
|
||||
}
|
||||
|
||||
// Missing output in _plugin_outputs means that the network is dynamic and outputs couldn't be pre-allocated
|
||||
if (m_plugin_outputs.find(name) == m_plugin_outputs.end())
|
||||
return {};
|
||||
|
||||
auto output_tensor = std::dynamic_pointer_cast<RemoteTensorImpl>(m_plugin_outputs.at(name).ptr);
|
||||
auto output_memory = output_tensor->get_memory();
|
||||
return network->set_output_memory(internal_name, output_memory);
|
||||
}
|
||||
|
||||
void SyncInferRequest::init_mappings(bool is_legacy_api) {
|
||||
for (const auto& in : get_inputs()) {
|
||||
auto port_name = get_port_name(in, is_legacy_api);
|
||||
m_input_ports_map[port_name] = in;
|
||||
}
|
||||
for (const auto& out : get_outputs()) {
|
||||
auto port_name = get_port_name(out, is_legacy_api);
|
||||
m_output_ports_map[port_name] = out;
|
||||
m_output_names_map[port_name] = m_graph->out_name_to_internal(port_name);
|
||||
}
|
||||
}
|
||||
|
||||
bool SyncInferRequest::is_batched_input(const ov::Output<const ov::Node>& port) const {
|
||||
return m_batched_tensors.count(port.get_tensor_ptr()) > 0;
|
||||
}
|
||||
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
@@ -36,7 +36,7 @@ std::vector<std::pair<size_t, size_t>> compute_einsum_path(std::shared_ptr<const
|
||||
// TODO: implement algorithm for finding (pseudo-)optimal einsum_path
|
||||
std::vector<std::pair<size_t, size_t>> einsum_path;
|
||||
const size_t num_inputs = einsum_node->get_input_size();
|
||||
NGRAPH_CHECK(num_inputs > 0);
|
||||
OPENVINO_ASSERT(num_inputs > 0);
|
||||
for (size_t input_ind = num_inputs - 1; input_ind > 0; --input_ind) {
|
||||
einsum_path.push_back(std::make_pair(0, input_ind));
|
||||
}
|
||||
@@ -141,9 +141,9 @@ std::string generate_grouping_subscript(const std::string& input_subscript, cons
|
||||
///
|
||||
void update_operands(ov::OutputVector& input_nodes, std::vector<std::string>& input_subscripts, size_t input_ind1, size_t input_ind2,
|
||||
const ov::Output<ov::Node>& new_node, const std::string& new_subscript) {
|
||||
NGRAPH_CHECK(input_ind1 < input_ind2);
|
||||
NGRAPH_CHECK(input_ind2 < input_nodes.size());
|
||||
NGRAPH_CHECK(input_ind2 < input_subscripts.size());
|
||||
OPENVINO_ASSERT(input_ind1 < input_ind2);
|
||||
OPENVINO_ASSERT(input_ind2 < input_nodes.size());
|
||||
OPENVINO_ASSERT(input_ind2 < input_subscripts.size());
|
||||
input_nodes.erase(input_nodes.begin() + input_ind2);
|
||||
input_nodes.erase(input_nodes.begin() + input_ind1);
|
||||
input_nodes.push_back(new_node);
|
||||
@@ -163,7 +163,7 @@ void update_operands(ov::OutputVector& input_nodes, std::vector<std::string>& in
|
||||
/// \return sub-shape
|
||||
///
|
||||
ov::Shape compute_sub_shape(const ov::Shape& input_shape, size_t begin, size_t end, bool is_product = false) {
|
||||
NGRAPH_CHECK(end <= input_shape.size());
|
||||
OPENVINO_ASSERT(end <= input_shape.size());
|
||||
if (end <= begin) {
|
||||
return ov::Shape();
|
||||
}
|
||||
@@ -260,12 +260,12 @@ LabelDimMap compute_label_dim_map(const ov::Rank& input_rank,
|
||||
static const std::string ellipsis = "...";
|
||||
const auto labels = ov::op::v7::Einsum::extract_labels(input_subscript);
|
||||
const auto static_input_rank = input_rank.is_static();
|
||||
NGRAPH_CHECK(static_input_rank || (std::find(labels.begin(), labels.end(), ellipsis) == labels.end()),
|
||||
OPENVINO_ASSERT(static_input_rank || (std::find(labels.begin(), labels.end(), ellipsis) == labels.end()),
|
||||
"Input rank cannot be dynamic in case of ellipsis in input subscript");
|
||||
const size_t input_rank_length = static_input_rank ? input_rank.get_length() : labels.size();
|
||||
NGRAPH_CHECK(input_rank_length >= labels.size());
|
||||
OPENVINO_ASSERT(input_rank_length >= labels.size());
|
||||
const size_t num_broadcasted_dims = input_rank_length - labels.size() + 1;
|
||||
NGRAPH_CHECK(num_broadcasted_dims > 0);
|
||||
OPENVINO_ASSERT(num_broadcasted_dims > 0);
|
||||
|
||||
LabelDimMap resulted_map;
|
||||
size_t current_dim = 0;
|
||||
@@ -304,8 +304,8 @@ void transpose_input(ov::OutputVector& input_nodes, std::vector<std::string>& in
|
||||
ov::NodeVector& subgraph_nodes) {
|
||||
// perform sanity check for arguments
|
||||
const auto num_inputs = input_nodes.size();
|
||||
NGRAPH_CHECK(num_inputs == input_subscripts.size(), "Each input must have own subscript.");
|
||||
NGRAPH_CHECK(input_ind < num_inputs, "Input index is out of range.");
|
||||
OPENVINO_ASSERT(num_inputs == input_subscripts.size(), "Each input must have own subscript.");
|
||||
OPENVINO_ASSERT(input_ind < num_inputs, "Input index is out of range.");
|
||||
|
||||
// generate permutation vector by searching for bijection between input_subscripts
|
||||
// and required_subscript
|
||||
@@ -322,11 +322,11 @@ void transpose_input(ov::OutputVector& input_nodes, std::vector<std::string>& in
|
||||
const auto& input_node = input_nodes[input_ind];
|
||||
const auto labels = ov::op::v7::Einsum::extract_labels(input_subscript);
|
||||
const auto required_labels = ov::op::v7::Einsum::extract_labels(required_subscript);
|
||||
NGRAPH_CHECK(labels.size() == required_labels.size());
|
||||
OPENVINO_ASSERT(labels.size() == required_labels.size());
|
||||
const auto label_dim_map = compute_label_dim_map(input_node.get_partial_shape().rank(), input_subscript);
|
||||
for (const auto& required_label : required_labels) {
|
||||
const auto label_dims_it = label_dim_map.find(required_label);
|
||||
NGRAPH_CHECK(label_dims_it != label_dim_map.end());
|
||||
OPENVINO_ASSERT(label_dims_it != label_dim_map.end());
|
||||
const auto& label_dims = label_dims_it->second;
|
||||
permutation.insert(permutation.end(), label_dims.begin(), label_dims.end());
|
||||
}
|
||||
@@ -360,8 +360,8 @@ void reduce_input(EinsumDecomposition *einsum_decompose_ptr,
|
||||
const std::string& output_subscript, size_t input_ind, ov::NodeVector& subgraph_nodes) {
|
||||
// perform sanity check for arguments
|
||||
const auto num_inputs = input_nodes.size();
|
||||
NGRAPH_CHECK(num_inputs == input_subscripts.size(), "Each input must have own subscript.");
|
||||
NGRAPH_CHECK(input_ind < num_inputs, "Input index is out of range.");
|
||||
OPENVINO_ASSERT(num_inputs == input_subscripts.size(), "Each input must have own subscript.");
|
||||
OPENVINO_ASSERT(input_ind < num_inputs, "Input index is out of range.");
|
||||
|
||||
const auto& input_node = input_nodes[input_ind];
|
||||
const auto& input_subscript = input_subscripts[input_ind];
|
||||
@@ -377,7 +377,7 @@ void reduce_input(EinsumDecomposition *einsum_decompose_ptr,
|
||||
// or the output subscript
|
||||
const bool is_dim_reduced = is_dimension_reduced(input_subscripts, output_subscript, label, {input_ind});
|
||||
|
||||
NGRAPH_CHECK(label_dim_map.find(label) != label_dim_map.end());
|
||||
OPENVINO_ASSERT(label_dim_map.find(label) != label_dim_map.end());
|
||||
const auto& label_dims = label_dim_map[label];
|
||||
|
||||
// if label is not met, dimension corresponding to the label is to reduce
|
||||
@@ -416,7 +416,7 @@ void broadcast_input(ov::OutputVector& inputs,
|
||||
const ov::Shape& reduced_shape,
|
||||
bool is_separate_first,
|
||||
ov::NodeVector& subgraph_nodes) {
|
||||
NGRAPH_CHECK(input_ind < inputs.size());
|
||||
OPENVINO_ASSERT(input_ind < inputs.size());
|
||||
const auto& input = inputs[input_ind];
|
||||
|
||||
ov::Shape new_shape{new_common_shape.begin(), new_common_shape.end()};
|
||||
@@ -434,7 +434,7 @@ void broadcast_input(ov::OutputVector& inputs,
|
||||
}
|
||||
const auto old_shape_size = old_shape.size();
|
||||
const auto new_shape_size = new_shape.size();
|
||||
NGRAPH_CHECK(old_shape_size <= new_shape_size);
|
||||
OPENVINO_ASSERT(old_shape_size <= new_shape_size);
|
||||
|
||||
const auto new_shape_const = ov::op::v0::Constant::create(ov::element::Type_t::i64, ov::Shape {new_shape.size()}, new_shape);
|
||||
const auto broadcast = std::make_shared<ov::op::v3::Broadcast>(input, new_shape_const, ov::op::BroadcastType::NUMPY);
|
||||
@@ -447,13 +447,13 @@ void broadcast_input(ov::OutputVector& inputs,
|
||||
ov::Output<ov::Node> build_identity(const ov::Output<ov::Node>& input_node,
|
||||
const std::vector<size_t>& repeated_label_dims,
|
||||
ov::NodeVector& subgraph_nodes) {
|
||||
NGRAPH_CHECK(repeated_label_dims.size() > 1);
|
||||
OPENVINO_ASSERT(repeated_label_dims.size() > 1);
|
||||
const auto input_shape = input_node.get_shape();
|
||||
ov::Shape identity_shape(input_shape.size(), 1);
|
||||
const size_t repeated_label_dim_size = input_shape[repeated_label_dims[0]];
|
||||
for (const auto dim : repeated_label_dims) {
|
||||
NGRAPH_CHECK(dim < input_shape.size());
|
||||
NGRAPH_CHECK(repeated_label_dim_size == input_shape[dim]);
|
||||
OPENVINO_ASSERT(dim < input_shape.size());
|
||||
OPENVINO_ASSERT(repeated_label_dim_size == input_shape[dim]);
|
||||
identity_shape[dim] = repeated_label_dim_size;
|
||||
}
|
||||
|
||||
@@ -481,11 +481,11 @@ ov::Output<ov::Node> build_multi_identity(EinsumDecomposition* einsum_decompose_
|
||||
const std::vector<std::string>& repeated_labels,
|
||||
const LabelDimMap& label_dim_map,
|
||||
ov::NodeVector& subgraph_nodes) {
|
||||
NGRAPH_CHECK(repeated_labels.size() > 0);
|
||||
OPENVINO_ASSERT(repeated_labels.size() > 0);
|
||||
|
||||
const auto get_identity = [&](size_t idx) {
|
||||
const auto repeated_label_dims = label_dim_map.find(repeated_labels[idx]);
|
||||
NGRAPH_CHECK(repeated_label_dims != label_dim_map.end());
|
||||
OPENVINO_ASSERT(repeated_label_dims != label_dim_map.end());
|
||||
return build_identity(input_node, repeated_label_dims->second, subgraph_nodes);
|
||||
};
|
||||
|
||||
@@ -522,11 +522,11 @@ void prepare_diagonal_extraction_data(
|
||||
}
|
||||
|
||||
const auto dims_it = label_dim_map.find(label);
|
||||
NGRAPH_CHECK(dims_it != label_dim_map.end());
|
||||
OPENVINO_ASSERT(dims_it != label_dim_map.end());
|
||||
|
||||
auto dims = dims_it->second;
|
||||
const auto dims_size = dims.size();
|
||||
NGRAPH_CHECK(dims_size > 0);
|
||||
OPENVINO_ASSERT(dims_size > 0);
|
||||
|
||||
if (label != ellipsis && dims_size > 1) {
|
||||
// repeated label is found
|
||||
@@ -539,7 +539,7 @@ void prepare_diagonal_extraction_data(
|
||||
}
|
||||
resultant_subscript += label;
|
||||
for (const auto dim : dims) {
|
||||
NGRAPH_CHECK(dim < input_shape.size());
|
||||
OPENVINO_ASSERT(dim < input_shape.size());
|
||||
result_shape.push_back(input_shape[dim]);
|
||||
}
|
||||
}
|
||||
@@ -552,8 +552,8 @@ void extract_diagonal(EinsumDecomposition* einsum_decompose_ptr,
|
||||
ov::NodeVector& subgraph_nodes) {
|
||||
// perform sanity check for arguments
|
||||
const auto num_inputs = inputs.size();
|
||||
NGRAPH_CHECK(num_inputs == input_subscripts.size(), "Each input must have own subscript.");
|
||||
NGRAPH_CHECK(input_ind < num_inputs, "Input index is out of range.");
|
||||
OPENVINO_ASSERT(num_inputs == input_subscripts.size(), "Each input must have own subscript.");
|
||||
OPENVINO_ASSERT(input_ind < num_inputs, "Input index is out of range.");
|
||||
|
||||
const auto& input_node = inputs[input_ind];
|
||||
const auto& input_subscript = input_subscripts[input_ind];
|
||||
@@ -604,19 +604,19 @@ void compute_ranges(const ov::Rank& input_rank,
|
||||
|
||||
size_t common_rank = common_labels.size();
|
||||
if (std::find(common_labels.begin(), common_labels.end(), ellipsis) != common_labels.end()) {
|
||||
NGRAPH_CHECK(label_to_dim_map.find(ellipsis) != label_to_dim_map.end());
|
||||
OPENVINO_ASSERT(label_to_dim_map.find(ellipsis) != label_to_dim_map.end());
|
||||
common_rank += label_to_dim_map[ellipsis].size() - 1;
|
||||
}
|
||||
|
||||
size_t sep_rank = sep_labels.size();
|
||||
if (std::find(sep_labels.begin(), sep_labels.end(), ellipsis) != sep_labels.end()) {
|
||||
NGRAPH_CHECK(label_to_dim_map.find(ellipsis) != label_to_dim_map.end());
|
||||
OPENVINO_ASSERT(label_to_dim_map.find(ellipsis) != label_to_dim_map.end());
|
||||
sep_rank += label_to_dim_map[ellipsis].size() - 1;
|
||||
}
|
||||
|
||||
size_t reduced_rank = reduced_labels.size();
|
||||
if (std::find(reduced_labels.begin(), reduced_labels.end(), ellipsis) != reduced_labels.end()) {
|
||||
NGRAPH_CHECK(label_to_dim_map.find(ellipsis) != label_to_dim_map.end());
|
||||
OPENVINO_ASSERT(label_to_dim_map.find(ellipsis) != label_to_dim_map.end());
|
||||
reduced_rank += label_to_dim_map[ellipsis].size() - 1;
|
||||
}
|
||||
|
||||
@@ -660,8 +660,8 @@ void contract_two_inputs(EinsumDecomposition* einsum_decompose_ptr,
|
||||
|
||||
// perform sanity check for arguments
|
||||
auto num_inputs = input_nodes.size();
|
||||
NGRAPH_CHECK(num_inputs == input_subscripts.size(), "Each input must have own subscript.");
|
||||
NGRAPH_CHECK(input_ind2 < num_inputs && input_ind1 != input_ind2, "Incorrect input index is specified.");
|
||||
OPENVINO_ASSERT(num_inputs == input_subscripts.size(), "Each input must have own subscript.");
|
||||
OPENVINO_ASSERT(input_ind2 < num_inputs && input_ind1 != input_ind2, "Incorrect input index is specified.");
|
||||
|
||||
const auto& input_node1 = input_nodes[input_ind1];
|
||||
const auto& input_node2 = input_nodes[input_ind2];
|
||||
@@ -746,7 +746,7 @@ void contract_two_inputs(EinsumDecomposition* einsum_decompose_ptr,
|
||||
std::vector<int64_t> unsqueeze_axis1;
|
||||
std::vector<int64_t> unsqueeze_axis2;
|
||||
for (const auto& sep_label2 : separate_labels2) {
|
||||
NGRAPH_CHECK(label_to_dim_map2.find(sep_label2) != label_to_dim_map2.end());
|
||||
OPENVINO_ASSERT(label_to_dim_map2.find(sep_label2) != label_to_dim_map2.end());
|
||||
const auto label_dims = label_to_dim_map2[sep_label2];
|
||||
for (size_t dim_ind = 0; dim_ind < label_dims.size(); ++dim_ind) {
|
||||
unsqueeze_axis1.push_back(unsqueeze_dim + static_cast<int64_t>(dim_ind));
|
||||
@@ -754,7 +754,7 @@ void contract_two_inputs(EinsumDecomposition* einsum_decompose_ptr,
|
||||
++unsqueeze_dim;
|
||||
}
|
||||
for (const auto& sep_label1 : separate_labels1) {
|
||||
NGRAPH_CHECK(label_to_dim_map1.find(sep_label1) != label_to_dim_map1.end());
|
||||
OPENVINO_ASSERT(label_to_dim_map1.find(sep_label1) != label_to_dim_map1.end());
|
||||
const auto label_dims = label_to_dim_map1[sep_label1];
|
||||
for (const auto label_dim : label_dims) {
|
||||
unsqueeze_axis2.push_back(label_dim);
|
||||
@@ -928,7 +928,7 @@ EinsumDecomposition::EinsumDecomposition() {
|
||||
extract_diagonal(this, input_nodes, input_subscripts, 0, subgraph_nodes);
|
||||
|
||||
// reduce dimensions for the remained input node
|
||||
NGRAPH_CHECK(input_nodes.size() == 1);
|
||||
OPENVINO_ASSERT(input_nodes.size() == 1);
|
||||
reduce_input(this, input_nodes, input_subscripts, output_subscript, 0, subgraph_nodes);
|
||||
|
||||
// transpose dimensions to layout required by the output subscript
|
||||
|
||||
@@ -229,9 +229,11 @@ void TransformationsPipeline::apply(std::shared_ptr<ov::Model> func) {
|
||||
pass_config->set_callback<ov::pass::KeepConstAndDecompression>(is_matmul_output);
|
||||
|
||||
const bool keep_precision_sensitive_in_fp32_1 = true;
|
||||
const bool convert_input_output_precision = false;
|
||||
manager.register_pass<ov::pass::ConvertPrecision>(fp_convert_precision_map,
|
||||
empty_fuse_map,
|
||||
keep_precision_sensitive_in_fp32_1);
|
||||
keep_precision_sensitive_in_fp32_1,
|
||||
convert_input_output_precision);
|
||||
|
||||
manager.register_pass<ov::pass::CommonOptimizations>();
|
||||
|
||||
@@ -283,7 +285,11 @@ void TransformationsPipeline::apply(std::shared_ptr<ov::Model> func) {
|
||||
};
|
||||
|
||||
manager.register_pass<ov::pass::Validate>();
|
||||
manager.register_pass<ov::pass::ConvertPrecision>(int_convert_precision_map);
|
||||
const bool keep_precision_sensitive_in_fp32_2 = true;
|
||||
manager.register_pass<ov::pass::ConvertPrecision>(int_convert_precision_map,
|
||||
empty_fuse_map,
|
||||
keep_precision_sensitive_in_fp32_2,
|
||||
convert_input_output_precision);
|
||||
|
||||
pass_config->disable<ov::pass::EyeDecomposition>();
|
||||
|
||||
|
||||
@@ -1,69 +1,52 @@
|
||||
// Copyright (C) 2018-2023 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
#include <intel_gpu/plugin/variable_state.hpp>
|
||||
#include <blob_factory.hpp>
|
||||
|
||||
#include "openvino/runtime/make_tensor.hpp"
|
||||
#include "intel_gpu/plugin/remote_tensor.hpp"
|
||||
#include "intel_gpu/plugin/variable_state.hpp"
|
||||
#include "intel_gpu/runtime/layout.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
VariableState::VariableState(const std::string &name,
|
||||
const std::vector<cldnn::network::VariableState::Ptr> &states,
|
||||
cldnn::engine& engine, int currentBatch)
|
||||
: InferenceEngine::IVariableStateInternal {name}
|
||||
, currentBatch_ {currentBatch}
|
||||
, states_ {states}
|
||||
, desc_ {
|
||||
PrecisionFromDataType(states.front()->memory->get_layout().data_type),
|
||||
AggregateShape(states.front()->memory->get_layout()),
|
||||
InferenceEngine::Layout::ANY
|
||||
VariableState::VariableState(const std::string &name, cldnn::network::VariableState::Ptr state, cldnn::engine& engine)
|
||||
: ov::IVariableState {name}
|
||||
, m_variable_state(state)
|
||||
, m_engine(engine) {
|
||||
auto internal_memory = m_variable_state->memory;
|
||||
auto internal_layout = internal_memory->get_layout();
|
||||
auto et = cldnn::data_type_to_element_type(internal_layout.data_type);
|
||||
auto shape = internal_layout.get_shape();
|
||||
m_state = ov::make_tensor(et, shape);
|
||||
}
|
||||
|
||||
void VariableState::reset() {
|
||||
m_variable_state->is_set = false;
|
||||
}
|
||||
|
||||
void VariableState::set_state(const ov::SoPtr<ov::ITensor>& state) {
|
||||
const bool blocking = true;
|
||||
auto remote_ptr = std::dynamic_pointer_cast<RemoteTensorImpl>(state._ptr);
|
||||
if (remote_ptr != nullptr) {
|
||||
auto user_memory = remote_ptr->get_memory();
|
||||
cldnn::mem_lock<uint8_t> lock(user_memory, m_engine.get_service_stream());
|
||||
m_variable_state->memory->copy_from(m_engine.get_service_stream(), lock.data(), blocking);
|
||||
} else {
|
||||
auto data = state->data();
|
||||
m_variable_state->memory->copy_from(m_engine.get_service_stream(), data, blocking);
|
||||
}
|
||||
, engine_(engine) { }
|
||||
|
||||
void VariableState::Reset() {
|
||||
IterateOverStates([](cldnn::network::VariableState &state) {
|
||||
state.is_set = false;
|
||||
});
|
||||
m_variable_state->is_set = true;
|
||||
}
|
||||
|
||||
void VariableState::SetState(const InferenceEngine::Blob::Ptr &newState) {
|
||||
auto lock = std::dynamic_pointer_cast<InferenceEngine::MemoryBlob>(newState)->rmap();
|
||||
auto data = lock.as<char*>();
|
||||
IterateOverStates([&data, this](cldnn::network::VariableState &state) {
|
||||
state.memory->copy_from(engine_.get_service_stream(), data);
|
||||
data += state.memory->get_layout().bytes_count();
|
||||
state.is_set = true;
|
||||
});
|
||||
engine_.get_service_stream().enqueue_barrier();
|
||||
}
|
||||
const ov::SoPtr<ov::ITensor>& VariableState::get_state() const {
|
||||
auto internal_memory = m_variable_state->memory;
|
||||
const bool blocking = true;
|
||||
internal_memory->copy_to(m_engine.get_service_stream(), m_state->data(), blocking);
|
||||
|
||||
InferenceEngine::Blob::CPtr VariableState::GetState() const {
|
||||
auto blob = make_blob_with_precision(desc_, InferenceEngine::CreateDefaultAllocator());
|
||||
blob->allocate();
|
||||
auto blobLock = std::dynamic_pointer_cast<InferenceEngine::MemoryBlob>(blob)->wmap();
|
||||
auto data = blobLock.as<char*>();
|
||||
IterateOverStates([&data, this](cldnn::network::VariableState &state) {
|
||||
cldnn::mem_lock<char, cldnn::mem_lock_type::read> lock { state.memory, engine_.get_service_stream() };
|
||||
std::copy(lock.begin(), lock.end(), data);
|
||||
data += state.memory->get_layout().bytes_count();
|
||||
});
|
||||
return blob;
|
||||
}
|
||||
|
||||
InferenceEngine::SizeVector VariableState::AggregateShape(const cldnn::layout &layout) {
|
||||
const auto& dims = layout.get_dims();
|
||||
InferenceEngine::SizeVector shape {dims.begin(), dims.end()};
|
||||
if (currentBatch_ != -1)
|
||||
shape.front() = currentBatch_;
|
||||
return shape;
|
||||
}
|
||||
|
||||
void VariableState::IterateOverStates(std::function<void(cldnn::network::VariableState&)> f) const {
|
||||
for (size_t i = 0; i < states_.size(); i++) {
|
||||
auto batch = 1 << i;
|
||||
if (batch & currentBatch_)
|
||||
f(*states_[i]);
|
||||
}
|
||||
return m_state;
|
||||
}
|
||||
|
||||
} // namespace intel_gpu
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright (C) 2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "intel_gpu/runtime/file_util.hpp"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace ov {
|
||||
namespace intel_gpu {
|
||||
|
||||
void save_binary(const std::string &path, std::vector<uint8_t> binary) {
|
||||
try {
|
||||
ov::util::save_binary(path, binary);
|
||||
} catch (std::runtime_error&) {}
|
||||
}
|
||||
|
||||
} // namespace intel_gpu
|
||||
} // namespace ov
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "intel_gpu/graph/serialization/string_serializer.hpp"
|
||||
#include "intel_gpu/runtime/debug_configuration.hpp"
|
||||
#include "intel_gpu/runtime/itt.hpp"
|
||||
#include "openvino/util/file_util.hpp"
|
||||
#include "intel_gpu/runtime/file_util.hpp"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <sdkddkver.h>
|
||||
@@ -272,7 +272,7 @@ void kernels_cache::build_batch(const engine& build_engine, const batch_program&
|
||||
// Bucket size can be changed in get_max_kernels_per_batch() method, but forcing it to 1 will lead to much longer
|
||||
// compile time.
|
||||
std::lock_guard<std::mutex> lock(cacheAccessMutex);
|
||||
ov::util::save_binary(cached_bin_name, getProgramBinaries(program));
|
||||
ov::intel_gpu::save_binary(cached_bin_name, getProgramBinaries(program));
|
||||
}
|
||||
} else {
|
||||
cl::Program program(cl_build_engine.get_cl_context(), {cl_build_engine.get_cl_device()}, precompiled_kernels);
|
||||
|
||||
@@ -32,7 +32,7 @@ cl::PFN_clCreateFromD3D11Buffer cl::BufferDX::pfn_clCreateFromD3D11Buffer = NULL
|
||||
|
||||
#ifdef ENABLE_ONEDNN_FOR_GPU
|
||||
#include <oneapi/dnnl/dnnl_ocl.hpp>
|
||||
#include "openvino/util/file_util.hpp"
|
||||
#include "intel_gpu/runtime/file_util.hpp"
|
||||
#endif
|
||||
|
||||
namespace cldnn {
|
||||
@@ -89,7 +89,7 @@ void ocl_engine::create_onednn_engine(const ExecutionConfig& config) {
|
||||
_onednn_engine = std::make_shared<dnnl::engine>(dnnl::ocl_interop::make_engine(casted->get_device().get(), casted->get_context().get()));
|
||||
|
||||
onednn_cache_blob = dnnl::ocl_interop::get_engine_cache_blob(*_onednn_engine);
|
||||
ov::util::save_binary(path, onednn_cache_blob);
|
||||
ov::intel_gpu::save_binary(path, onednn_cache_blob);
|
||||
} else {
|
||||
_onednn_engine = std::make_shared<dnnl::engine>(dnnl::ocl_interop::make_engine(casted->get_device().get(), casted->get_context().get(),
|
||||
onednn_cache_blob));
|
||||
|
||||
@@ -176,15 +176,19 @@ gpu_image2d::gpu_image2d(ocl_engine* engine, const layout& layout)
|
||||
type = CL_UNORM_INT8;
|
||||
break;
|
||||
case format::nv12:
|
||||
_width = layout.spatial(1);
|
||||
_height = layout.spatial(0);
|
||||
if (layout.feature() == 2) {
|
||||
{
|
||||
// [NHWC] dimensions order
|
||||
auto shape = layout.get_shape();
|
||||
_width = shape[2];
|
||||
_height = shape[1];
|
||||
if (shape[3] == 2) {
|
||||
order = CL_RG;
|
||||
} else if (layout.feature() > 2) {
|
||||
} else if (shape[3] > 2) {
|
||||
CLDNN_ERROR_MESSAGE("2D image allocation", "invalid number of channels in NV12 input image!");
|
||||
}
|
||||
type = CL_UNORM_INT8;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CLDNN_ERROR_MESSAGE("2D image allocation", "unsupported image type!");
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "shared_test_classes/base/ov_subgraph.hpp"
|
||||
#include <cpp/ie_cnn_network.h>
|
||||
#include <ie_plugin_config.hpp>
|
||||
#include "functional_test_utils/skip_tests_config.hpp"
|
||||
#include "functional_test_utils/ov_plugin_cache.hpp"
|
||||
#include "common_test_utils/common_utils.hpp"
|
||||
|
||||
@@ -96,6 +97,7 @@ protected:
|
||||
};
|
||||
|
||||
TEST_P(MemoryDynamicBatch, MultipleInferencesOnTheSameInferRequest) {
|
||||
SKIP_IF_CURRENT_TEST_IS_DISABLED()
|
||||
auto compiledModel = core_->compile_model(model_, ov::test::utils::DEVICE_GPU, { });
|
||||
auto inferRequest = compiledModel.create_infer_request();
|
||||
input_ = generateInput(inputShape_);
|
||||
@@ -112,6 +114,7 @@ TEST_P(MemoryDynamicBatch, MultipleInferencesOnTheSameInferRequest) {
|
||||
}
|
||||
|
||||
TEST_P(MemoryDynamicBatch, ResetVariableState) {
|
||||
SKIP_IF_CURRENT_TEST_IS_DISABLED()
|
||||
auto compiledModel = core_->compile_model(model_, ov::test::utils::DEVICE_GPU, { });
|
||||
auto inferRequest = compiledModel.create_infer_request();
|
||||
input_ = generateInput(inputShape_);
|
||||
@@ -129,6 +132,7 @@ TEST_P(MemoryDynamicBatch, ResetVariableState) {
|
||||
}
|
||||
|
||||
TEST_P(MemoryDynamicBatch, GetVariableState) {
|
||||
SKIP_IF_CURRENT_TEST_IS_DISABLED()
|
||||
auto compiledModel = core_->compile_model(model_, ov::test::utils::DEVICE_GPU, { });
|
||||
auto inferRequest = compiledModel.create_infer_request();
|
||||
input_ = generateInput(inputShape_);
|
||||
@@ -145,6 +149,7 @@ TEST_P(MemoryDynamicBatch, GetVariableState) {
|
||||
}
|
||||
|
||||
TEST_P(MemoryDynamicBatch, SetVariableState) {
|
||||
SKIP_IF_CURRENT_TEST_IS_DISABLED()
|
||||
auto compiledModel = core_->compile_model(model_, ov::test::utils::DEVICE_GPU, { });
|
||||
auto inferRequest = compiledModel.create_infer_request();
|
||||
input_ = generateInput(inputShape_);
|
||||
|
||||
+42
-32
@@ -7,11 +7,12 @@
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "common_test_utils/test_assertions.hpp"
|
||||
#include "openvino/core/except.hpp"
|
||||
#include "openvino/runtime/intel_gpu/ocl/ocl.hpp"
|
||||
#include "openvino/runtime/core.hpp"
|
||||
#include "openvino/runtime/intel_gpu/properties.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>
|
||||
@@ -877,8 +878,8 @@ TEST_F(OVRemoteTensor_Test, NV12toGray) {
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Prepare input data
|
||||
ov::Tensor fake_image = ov::test::utils::create_and_fill_tensor(ov::element::i8, {1, feature, height, width}, 50, 0, 1);
|
||||
ov::Tensor fake_image_regular = ov::test::utils::create_and_fill_tensor(ov::element::f32, {1, feature, height, width});
|
||||
ov::Tensor fake_image = ov::test::utils::create_and_fill_tensor(ov::element::i8, {1, height, width, feature}, 50, 0, 1);
|
||||
ov::Tensor fake_image_regular = ov::test::utils::create_and_fill_tensor(ov::element::f32, {1, height, width, feature });
|
||||
|
||||
auto image_ptr = static_cast<uint8_t*>(fake_image.data());
|
||||
auto image_ptr_regular = static_cast<float*>(fake_image_regular.data());
|
||||
@@ -943,12 +944,13 @@ TEST_F(OVRemoteTensor_Test, NV12toGray) {
|
||||
|
||||
// ------------------------------------------------------
|
||||
// regular inference
|
||||
auto fn_ptr_regular = ngraph::builder::subgraph::makeConvPoolRelu({1, 1, height, width});
|
||||
auto fn_ptr_regular = ngraph::builder::subgraph::makeConvPoolRelu({1, feature, height, width});
|
||||
|
||||
auto p_reg = PrePostProcessor(fn_ptr_regular);
|
||||
p_reg.input().tensor().set_element_type(ov::element::f32)
|
||||
.set_layout("NHWC")
|
||||
.set_memory_type(ov::intel_gpu::memory_type::buffer);
|
||||
p_reg.input().model().set_layout("NHWC");
|
||||
p_reg.input().model().set_layout("NCHW");
|
||||
auto function_regular = p_reg.build();
|
||||
|
||||
auto param_input_y_regular = function_regular->get_parameters().at(0);
|
||||
@@ -978,8 +980,8 @@ TEST_F(OVRemoteTensor_Test, NV12toBGR_image_ConvertTranspose) {
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Prepare input data
|
||||
ov::Tensor fake_image_data_y = ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, 1, height, width}, 50, 0, 1);
|
||||
ov::Tensor fake_image_data_uv = ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, 2, height / 2, width / 2}, 256, 0, 1);
|
||||
ov::Tensor fake_image_data_y = ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, height, width, 1}, 50, 0, 1);
|
||||
ov::Tensor fake_image_data_uv = ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, height / 2, width / 2, 2}, 256, 0, 1);
|
||||
|
||||
auto ie = ov::Core();
|
||||
|
||||
@@ -991,7 +993,7 @@ TEST_F(OVRemoteTensor_Test, NV12toBGR_image_ConvertTranspose) {
|
||||
auto p = PrePostProcessor(fn_ptr_remote);
|
||||
p.input().tensor().set_element_type(ov::element::u8)
|
||||
.set_color_format(ColorFormat::NV12_TWO_PLANES, {"y", "uv"})
|
||||
.set_memory_type(GPU_CONFIG_KEY(SURFACE));
|
||||
.set_memory_type(ov::intel_gpu::memory_type::surface);
|
||||
p.input().preprocess().convert_color(ColorFormat::BGR);
|
||||
p.input().model().set_layout("NCHW");
|
||||
auto function = p.build();
|
||||
@@ -1056,7 +1058,7 @@ TEST_F(OVRemoteTensor_Test, NV12toBGR_image_ConvertTranspose) {
|
||||
auto p_reg = PrePostProcessor(fn_ptr_regular);
|
||||
p_reg.input().tensor().set_element_type(ov::element::u8)
|
||||
.set_color_format(ColorFormat::NV12_TWO_PLANES, {"y", "uv"})
|
||||
.set_memory_type(GPU_CONFIG_KEY(BUFFER));
|
||||
.set_memory_type(ov::intel_gpu::memory_type::buffer);
|
||||
p_reg.input().preprocess().convert_color(ColorFormat::BGR);
|
||||
p_reg.input().model().set_layout("NCHW");
|
||||
auto function_regular = p_reg.build();
|
||||
@@ -1087,7 +1089,7 @@ TEST_F(OVRemoteTensor_Test, NV12toBGR_image_single_plane) {
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Prepare input data
|
||||
ov::Tensor fake_image_data_yuv = ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, 1, height * 3 / 2, width}, 50);
|
||||
ov::Tensor fake_image_data_yuv = ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, height * 3 / 2, width, 1}, 50);
|
||||
|
||||
auto ie = ov::Core();
|
||||
|
||||
@@ -1099,7 +1101,7 @@ TEST_F(OVRemoteTensor_Test, NV12toBGR_image_single_plane) {
|
||||
auto p = PrePostProcessor(fn_ptr_remote);
|
||||
p.input().tensor().set_element_type(ov::element::u8)
|
||||
.set_color_format(ColorFormat::NV12_SINGLE_PLANE)
|
||||
.set_memory_type(GPU_CONFIG_KEY(SURFACE));
|
||||
.set_memory_type(ov::intel_gpu::memory_type::surface);
|
||||
p.input().preprocess().convert_color(ColorFormat::BGR);
|
||||
p.input().model().set_layout("NCHW");
|
||||
auto function = p.build();
|
||||
@@ -1147,7 +1149,7 @@ TEST_F(OVRemoteTensor_Test, NV12toBGR_image_single_plane) {
|
||||
auto p_reg = PrePostProcessor(fn_ptr_regular);
|
||||
p_reg.input().tensor().set_element_type(ov::element::u8)
|
||||
.set_color_format(ColorFormat::NV12_SINGLE_PLANE)
|
||||
.set_memory_type(GPU_CONFIG_KEY(BUFFER));
|
||||
.set_memory_type(ov::intel_gpu::memory_type::buffer);
|
||||
p_reg.input().preprocess().convert_color(ColorFormat::BGR);
|
||||
p_reg.input().model().set_layout("NCHW");
|
||||
auto function_regular = p_reg.build();
|
||||
@@ -1177,8 +1179,8 @@ TEST_F(OVRemoteTensor_Test, NV12toBGR_image_two_planes) {
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Prepare input data
|
||||
ov::Tensor fake_image_data_y = ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, 1, height, width}, 50, 0, 1);
|
||||
ov::Tensor fake_image_data_uv = ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, 2, height / 2, width / 2}, 256, 0, 1);
|
||||
ov::Tensor fake_image_data_y = ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, height, width, 1}, 50, 0, 1);
|
||||
ov::Tensor fake_image_data_uv = ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, height / 2, width / 2, 2}, 256, 0, 1);
|
||||
|
||||
auto ie = ov::Core();
|
||||
|
||||
@@ -1190,7 +1192,7 @@ TEST_F(OVRemoteTensor_Test, NV12toBGR_image_two_planes) {
|
||||
auto p = PrePostProcessor(fn_ptr_remote);
|
||||
p.input().tensor().set_element_type(ov::element::u8)
|
||||
.set_color_format(ColorFormat::NV12_TWO_PLANES, {"y", "uv"})
|
||||
.set_memory_type(GPU_CONFIG_KEY(SURFACE));
|
||||
.set_memory_type(ov::intel_gpu::memory_type::surface);
|
||||
p.input().preprocess().convert_color(ColorFormat::BGR);
|
||||
p.input().model().set_layout("NCHW");
|
||||
auto function = p.build();
|
||||
@@ -1255,7 +1257,7 @@ TEST_F(OVRemoteTensor_Test, NV12toBGR_image_two_planes) {
|
||||
auto p_reg = PrePostProcessor(fn_ptr_regular);
|
||||
p_reg.input().tensor().set_element_type(ov::element::u8)
|
||||
.set_color_format(ColorFormat::NV12_TWO_PLANES, {"y", "uv"})
|
||||
.set_memory_type(GPU_CONFIG_KEY(BUFFER));
|
||||
.set_memory_type(ov::intel_gpu::memory_type::buffer);
|
||||
p_reg.input().preprocess().convert_color(ColorFormat::BGR);
|
||||
p_reg.input().model().set_layout("NCHW");
|
||||
auto function_regular = p_reg.build();
|
||||
@@ -1286,8 +1288,8 @@ TEST_F(OVRemoteTensor_Test, NV12toBGR_buffer) {
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Prepare input data
|
||||
ov::Tensor fake_image_data_y = ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, 1, height, width}, 50, 0, 1);
|
||||
ov::Tensor fake_image_data_uv = ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, 2, height / 2, width / 2}, 256, 0, 1);
|
||||
ov::Tensor fake_image_data_y = ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, height, width, 1}, 50, 0, 1);
|
||||
ov::Tensor fake_image_data_uv = ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, height / 2, width / 2, 2}, 256, 0, 1);
|
||||
|
||||
auto ie = ov::Core();
|
||||
|
||||
@@ -1297,7 +1299,7 @@ TEST_F(OVRemoteTensor_Test, NV12toBGR_buffer) {
|
||||
auto p = PrePostProcessor(fn_ptr_remote);
|
||||
p.input().tensor().set_element_type(ov::element::u8)
|
||||
.set_color_format(ColorFormat::NV12_TWO_PLANES, {"y", "uv"})
|
||||
.set_memory_type(GPU_CONFIG_KEY(BUFFER));
|
||||
.set_memory_type(ov::intel_gpu::memory_type::buffer);
|
||||
p.input().preprocess().convert_color(ColorFormat::BGR);
|
||||
p.input().model().set_layout("NCHW");
|
||||
auto function = p.build();
|
||||
@@ -1389,7 +1391,7 @@ TEST_P(OVRemoteTensorBatched_Test, NV12toBGR_image_single_plane) {
|
||||
std::vector<ov::Tensor> fake_image_data_yuv;
|
||||
for (size_t i = 0; i < num_batch; i++) {
|
||||
fake_image_data_yuv.push_back(ov::test::utils::create_and_fill_tensor(
|
||||
ov::element::u8, {1, 1, height * 3 / 2, width}, 50, 0, 1, static_cast<int32_t>(i)));
|
||||
ov::element::u8, {1, height * 3 / 2, width, 1}, 50, 0, 1, static_cast<int32_t>(i)));
|
||||
}
|
||||
|
||||
auto ie = ov::Core();
|
||||
@@ -1402,7 +1404,7 @@ TEST_P(OVRemoteTensorBatched_Test, NV12toBGR_image_single_plane) {
|
||||
auto p = PrePostProcessor(fn_ptr_remote);
|
||||
p.input().tensor().set_element_type(ov::element::u8)
|
||||
.set_color_format(ColorFormat::NV12_SINGLE_PLANE)
|
||||
.set_memory_type(GPU_CONFIG_KEY(SURFACE));
|
||||
.set_memory_type(ov::intel_gpu::memory_type::surface);
|
||||
p.input().preprocess().convert_color(ColorFormat::BGR);
|
||||
p.input().model().set_layout("NCHW");
|
||||
auto function = p.build();
|
||||
@@ -1460,7 +1462,7 @@ TEST_P(OVRemoteTensorBatched_Test, NV12toBGR_image_single_plane) {
|
||||
auto p_reg = PrePostProcessor(fn_ptr_regular);
|
||||
p_reg.input().tensor().set_element_type(ov::element::u8)
|
||||
.set_color_format(ColorFormat::NV12_SINGLE_PLANE)
|
||||
.set_memory_type(GPU_CONFIG_KEY(BUFFER));
|
||||
.set_memory_type(ov::intel_gpu::memory_type::buffer);
|
||||
p_reg.input().preprocess().convert_color(ColorFormat::BGR);
|
||||
p_reg.input().model().set_layout("NCHW");
|
||||
auto function_regular = p_reg.build();
|
||||
@@ -1495,9 +1497,9 @@ TEST_P(OVRemoteTensorBatched_Test, NV12toBGR_image_two_planes) {
|
||||
// Prepare input data
|
||||
std::vector<ov::Tensor> fake_image_data_y, fake_image_data_uv;
|
||||
for (size_t i = 0; i < num_batch; i++) {
|
||||
fake_image_data_y.push_back(ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, 1, height, width}, 50, 0, 1, static_cast<int32_t>(i)));
|
||||
fake_image_data_y.push_back(ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, height, width, 1}, 50, 0, 1, static_cast<int32_t>(i)));
|
||||
fake_image_data_uv.push_back(ov::test::utils::create_and_fill_tensor(
|
||||
ov::element::u8, {1, 2, height / 2, width / 2}, 256, 0, 1, static_cast<int32_t>(i)));
|
||||
ov::element::u8, {1, height / 2, width / 2, 2}, 256, 0, 1, static_cast<int32_t>(i)));
|
||||
}
|
||||
|
||||
auto ie = ov::Core();
|
||||
@@ -1510,7 +1512,7 @@ TEST_P(OVRemoteTensorBatched_Test, NV12toBGR_image_two_planes) {
|
||||
auto p = PrePostProcessor(fn_ptr_remote);
|
||||
p.input().tensor().set_element_type(ov::element::u8)
|
||||
.set_color_format(ColorFormat::NV12_TWO_PLANES, {"y", "uv"})
|
||||
.set_memory_type(GPU_CONFIG_KEY(SURFACE));
|
||||
.set_memory_type(ov::intel_gpu::memory_type::surface);
|
||||
p.input().preprocess().convert_color(ColorFormat::BGR);
|
||||
p.input().model().set_layout("NCHW");
|
||||
auto function = p.build();
|
||||
@@ -1584,7 +1586,7 @@ TEST_P(OVRemoteTensorBatched_Test, NV12toBGR_image_two_planes) {
|
||||
auto p_reg = PrePostProcessor(fn_ptr_regular);
|
||||
p_reg.input().tensor().set_element_type(ov::element::u8)
|
||||
.set_color_format(ColorFormat::NV12_TWO_PLANES, {"y", "uv"})
|
||||
.set_memory_type(GPU_CONFIG_KEY(BUFFER));
|
||||
.set_memory_type(ov::intel_gpu::memory_type::buffer);
|
||||
p_reg.input().preprocess().convert_color(ColorFormat::BGR);
|
||||
p_reg.input().model().set_layout("NCHW");
|
||||
auto function_regular = p_reg.build();
|
||||
@@ -1623,8 +1625,8 @@ TEST_P(OVRemoteTensorBatched_Test, NV12toGray) {
|
||||
std::vector<ov::Tensor> fake_image;
|
||||
std::vector<ov::Tensor> fake_image_regular;
|
||||
for (size_t i = 0; i < num_batch; i++) {
|
||||
auto tensor_image = ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, feature, height, width}, 50, 0, 1, static_cast<int32_t>(i));
|
||||
auto tensor_regular = ov::test::utils::create_and_fill_tensor(ov::element::f32, {1, feature, height, width});
|
||||
auto tensor_image = ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, height, width, feature}, 50, 0, 1, static_cast<int32_t>(i));
|
||||
auto tensor_regular = ov::test::utils::create_and_fill_tensor(ov::element::f32, {1, feature, height, width });
|
||||
auto image_ptr = static_cast<uint8_t*>(tensor_image.data());
|
||||
auto image_ptr_regular = static_cast<float*>(tensor_regular.data());
|
||||
// Apply NV12 (Surface) -> Gray conversion for regular blob
|
||||
@@ -1739,9 +1741,9 @@ TEST_P(OVRemoteTensorBatched_Test, NV12toBGR_buffer) {
|
||||
// Prepare input data
|
||||
std::vector<ov::Tensor> fake_image_data_y, fake_image_data_uv;
|
||||
for (size_t i = 0; i < num_batch * 2; ++i) {
|
||||
fake_image_data_y.push_back(ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, 1, height, width}, 50, 0, 1, static_cast<int32_t>(i)));
|
||||
fake_image_data_y.push_back(ov::test::utils::create_and_fill_tensor(ov::element::u8, {1, height, width, 1}, 50, 0, 1, static_cast<int32_t>(i)));
|
||||
fake_image_data_uv.push_back(ov::test::utils::create_and_fill_tensor(
|
||||
ov::element::u8, {1, 2, height / 2, width / 2}, 256, 0, 1, static_cast<int32_t>(i)));
|
||||
ov::element::u8, {1, height / 2, width / 2, 2}, 256, 0, 1, static_cast<int32_t>(i)));
|
||||
}
|
||||
|
||||
auto ie = ov::Core();
|
||||
@@ -1754,7 +1756,7 @@ TEST_P(OVRemoteTensorBatched_Test, NV12toBGR_buffer) {
|
||||
auto p = PrePostProcessor(fn_ptr_remote);
|
||||
p.input().tensor().set_element_type(ov::element::u8)
|
||||
.set_color_format(ColorFormat::NV12_TWO_PLANES, {"y", "uv"})
|
||||
.set_memory_type(GPU_CONFIG_KEY(BUFFER));
|
||||
.set_memory_type(ov::intel_gpu::memory_type::buffer);
|
||||
p.input().preprocess().convert_color(ColorFormat::BGR);
|
||||
p.input().model().set_layout("NCHW");
|
||||
auto function = p.build();
|
||||
@@ -1856,7 +1858,7 @@ TEST_P(OVRemoteTensorBatched_Test, NV12toBGR_buffer) {
|
||||
auto p_reg = PrePostProcessor(fn_ptr_regular);
|
||||
p_reg.input().tensor().set_element_type(ov::element::u8)
|
||||
.set_color_format(ColorFormat::NV12_TWO_PLANES, {"y", "uv"})
|
||||
.set_memory_type(GPU_CONFIG_KEY(BUFFER));
|
||||
.set_memory_type(ov::intel_gpu::memory_type::buffer);
|
||||
p_reg.input().preprocess().convert_color(ColorFormat::BGR);
|
||||
p_reg.input().model().set_layout("NCHW");
|
||||
auto function_regular = p_reg.build();
|
||||
@@ -1931,6 +1933,14 @@ TEST(OVRemoteContextGPU, smoke_CustomContextDeviceNames) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(OVRemoteContextGPU, smoke_CantCreateContextForNullHandle) {
|
||||
#if defined(ANDROID)
|
||||
GTEST_SKIP();
|
||||
#endif
|
||||
auto core = ov::Core();
|
||||
OV_EXPECT_THROW(ov::intel_gpu::ocl::ClContext(core, nullptr, 0), ov::Exception, HasSubstr("Can't create shared OCL context as user handle is nullptr!"));
|
||||
}
|
||||
|
||||
TEST(OVRemoteContextGPU, smoke_RemoteContextPerDevice) {
|
||||
#if defined(ANDROID)
|
||||
GTEST_SKIP();
|
||||
|
||||
+20
-33
@@ -9,14 +9,6 @@
|
||||
|
||||
std::vector<std::string> disabledTestPatterns() {
|
||||
return {
|
||||
// TODO: Issue: 39612
|
||||
R"(.*Interpolate.*cubic.*tf_half_pixel_for_nn.*FP16.*)",
|
||||
// TODO: Issue: 43794
|
||||
R"(.*(PreprocessTest).*(SetScalePreProcessSetBlob).*)",
|
||||
R"(.*(PreprocessTest).*(SetScalePreProcessGetBlob).*)",
|
||||
R"(.*(PreprocessTest).*(SetMeanValuePreProcessSetBlob).*)",
|
||||
R"(.*(PreprocessTest).*(SetMeanImagePreProcessSetBlob).*)",
|
||||
R"(.*(PreprocessTest).*(ReverseInputChannelsPreProcessGetBlob).*)",
|
||||
R"(.*(InferRequestPreprocessDynamicallyInSetBlobTest).*)",
|
||||
// TODO: Issue: 46841
|
||||
R"(.*(QuantGroupConvBackpropData3D).*)",
|
||||
@@ -39,8 +31,6 @@ std::vector<std::string> disabledTestPatterns() {
|
||||
R"(.*ConstantResultSubgraphTest.*inPrc=I16.*)",
|
||||
// TODO: Issue: 54194
|
||||
R"(.*ActivationLayerTest.*SoftPlus.*)",
|
||||
// need to implement Export / Import
|
||||
R"(.*IEClassImportExportTestP.*)",
|
||||
R"(.*Behavior.*InferRequestSetBlobByType.*Device=HETERO.*)",
|
||||
// TODO: Issue: 59586, NormalizeL2 output mismatch for empty axes case
|
||||
R"(.*NormalizeL2LayerTest.*axes=\(\).*)",
|
||||
@@ -51,15 +41,11 @@ std::vector<std::string> disabledTestPatterns() {
|
||||
R"(.*Behavior.*(Multi|Auto).*InferRequestSetBlobByType.*Batched.*)",
|
||||
R"(.*(Multi|Auto).*Behavior.*InferRequestIOBBlobTest.*canProcessDeallocatedOutputBlobAfterGetAndSetBlob.*)",
|
||||
// TODO Issue 100145
|
||||
R"(.*Behavior.*InferRequestIOBBlobTest.*canReallocateExternalBlobViaGet.*)",
|
||||
R"(.*Behavior.*OVInferRequestIOTensorTest.*canInferAfterIOBlobReallocation.*)",
|
||||
R"(.*Behavior.*OVInferRequestDynamicTests.*InferUpperBoundNetworkAfterIOTensorsReshaping.*)",
|
||||
R"(.*(Auto|Multi).*Behavior.*IncorrectConfigTests.*CanNotLoadNetworkWithIncorrectConfig.*)",
|
||||
// Not implemented yet:
|
||||
R"(.*Behavior.*ExecutableNetworkBaseTest.*canSetConfigToExecNet.*)",
|
||||
R"(.*Behavior.*ExecutableNetworkBaseTest.*canExport.*)",
|
||||
R"(.*OVCompiledModelBaseTest.*CanSetConfigToExecNet.*)",
|
||||
R"(.*OVCompiledModelBaseTest.*CanSetConfigToExecNetAndCheckConfigAndCheck.*)",
|
||||
// TODO: Issue 67408
|
||||
R"(.*smoke_LSTMSequenceCommonClip.*LSTMSequenceTest.*CompareWithRefs.*)",
|
||||
// TODO: Issue 114262
|
||||
@@ -68,17 +54,10 @@ std::vector<std::string> disabledTestPatterns() {
|
||||
R"(.*EltwiseLayerTest.*OpType=Pow.*NetType=i64.*)",
|
||||
// TODO: Issue: 68712
|
||||
R"(.*.MatMul.*CompareWithRefs.*IS0=\(1.5\)_IS1=\(1.5\).*transpose_a=0.*transpose_b=1.*CONSTANT.*FP16.*UNSPECIFIED.*UNSPECIFIED.*ANY.*)",
|
||||
// TODO: Issue 69187
|
||||
R"(smoke_PrePostProcess.*cvt_color_nv12.*)",
|
||||
// TODO: Issue 71215
|
||||
R"(smoke_PrePostProcess.*cvt_color_i420.*)",
|
||||
// Unsupported
|
||||
R"(smoke_Behavior/InferRequestSetBlobByType.setInputBlobsByType/BlobType=Batched_Device=GPU_Config=().*)",
|
||||
// TODO: Issue 72624
|
||||
R"(smoke_PrePostProcess.*resize_dynamic.*)",
|
||||
// Issue: CVS-66778
|
||||
R"(.*smoke_Auto_BehaviorTests.*DynamicOutputToDynamicInput.*)",
|
||||
R"(.*smoke_Auto_BehaviorTests.*DynamicInputToDynamicOutput.*)",
|
||||
// Dynamic batch allocates output using upper bound
|
||||
R"(.*smoke_BehaviorTests.*InferUpperBoundNetworkWithGetTensor.*)",
|
||||
// need dynamic shapes
|
||||
@@ -89,16 +68,8 @@ std::vector<std::string> disabledTestPatterns() {
|
||||
R"(.*smoke.*BehaviorTests.*DynamicInputToDynamicOutput.*)",
|
||||
// Issue: 76197
|
||||
R"(.*registerPluginsXMLUnicodePath.*)",
|
||||
// Not supported yet
|
||||
R"(.*CompileModelCacheTestBase.*ConvBias.*)",
|
||||
R"(.*CompileModelCacheTestBase.*KSOFunction.*)",
|
||||
R"(.*LoadNetworkCacheTestBase.*)",
|
||||
// Issue: 83014
|
||||
R"(.*smoke_RemoteBlob.*canInferOnUserQueue.*)",
|
||||
// Issue: CVS-76980
|
||||
R"(.*smoke_Auto_BehaviorTests.*InferDynamicNetwork/.*)",
|
||||
// Issue: CVS-86976
|
||||
R"(.*smoke_VirtualPlugin_BehaviorTests.*LoadedRemoteContext.*)",
|
||||
// Issue: CVS-88667 - Need to verify hetero interoperability
|
||||
R"(.*nightly_OVClassHeteroExecutableNetworlGetMetricTest.*SUPPORTED_(CONFIG_KEYS|METRICS).*)",
|
||||
// TODO: Issue: 89555
|
||||
@@ -132,10 +103,10 @@ std::vector<std::string> disabledTestPatterns() {
|
||||
R"(.*(Auto|Multi).*InferRequestPreprocessTest.*SetPreProcessToInputInfo.*)",
|
||||
R"(.*(Auto|Multi).*InferRequestPreprocessTest.*SetPreProcessToInferRequest.*)",
|
||||
// New plugin work with tensors, so it means that blob in old API can have different pointers
|
||||
R"(.*(Auto|Multi).*InferRequestIOBBlobTest.*secondCallGetInputDoNotReAllocateData.*)",
|
||||
R"(.*(Auto|Multi).*InferRequestIOBBlobTest.*secondCallGetOutputDoNotReAllocateData.*)",
|
||||
R"(.*(Auto|Multi).*InferRequestIOBBlobTest.*secondCallGetInputAfterInferSync.*)",
|
||||
R"(.*(Auto|Multi).*InferRequestIOBBlobTest.*secondCallGetOutputAfterInferSync.*)",
|
||||
R"(.*InferRequestIOBBlobTest.*secondCallGetInputDoNotReAllocateData.*)",
|
||||
R"(.*InferRequestIOBBlobTest.*secondCallGetOutputDoNotReAllocateData.*)",
|
||||
R"(.*InferRequestIOBBlobTest.*secondCallGetInputAfterInferSync.*)",
|
||||
R"(.*InferRequestIOBBlobTest.*secondCallGetOutputAfterInferSync.*)",
|
||||
// For some strange reason (bug?) output format cannot have a rank greater than 4 for dynamic shape case,
|
||||
// because it crashes in some random places during "reorder_inputs" pass.
|
||||
R"(.*UniqueLayerDynamicGPUTest.*\(\d*\.\d*\.\d*\.\d*\.\d*\).*axis.*)",
|
||||
@@ -143,5 +114,21 @@ std::vector<std::string> disabledTestPatterns() {
|
||||
// Plugin version was changed to ov::Version
|
||||
R"(.*VersionTest.*pluginCurrentVersionIsCorrect.*)",
|
||||
#endif
|
||||
// Old API cannot deallocate tensor
|
||||
R"(.*InferRequestIOBBlobTest.*canProcessDeallocatedOutputBlobAfterGetAndSetBlob.*)",
|
||||
// Issue: 113704 - Layout information maybe incorrect when covert tensor to blob
|
||||
R"(.*smoke_.*BehaviorTests/InferRequestPreprocessConversionTest.*NHWC.*)",
|
||||
// Issue: Disabled due to LPT precision matching issue
|
||||
R"(.*smoke_.*FakeQuantizeTransformation.*)",
|
||||
R"(.*smoke_LPT.*ReshapeTransformation.*)",
|
||||
R"(.*smoke_LPT.*ConvolutionTransformation.*)",
|
||||
R"(.*smoke_LPT.*MatMulWithConstantTransformation.*)",
|
||||
R"(.*smoke_LPT.*PullReshapeThroughDequantizationTransformation.*)",
|
||||
R"(.*smoke_LPT.*ElementwiseBranchSelectionTransformation.*)",
|
||||
// Dynamic state unsupported for now
|
||||
R"(.*MemoryDynamicBatch.*)",
|
||||
// Meta plugins may miss saving HW plugin so handle, thus plugin may be unloaded before all objects are deleted which leads to segfault
|
||||
// Issue: 118840
|
||||
R"(.*OVHoldersTest.*)",
|
||||
};
|
||||
}
|
||||
+1
-1
@@ -143,7 +143,7 @@ const std::vector<std::vector<ov::test::InputShape>> dynInputShapes = {
|
||||
// Input for ShapeOf
|
||||
{{ov::Dimension::dynamic(), ov::Dimension::dynamic(), ov::Dimension::dynamic()}, {{1, 10, 4}, {1, 4, 12}}},
|
||||
// Input for Add
|
||||
{{ov::Dimension::dynamic()}, {{1, 10, 4}, {2, 2, 12}}}
|
||||
{{ov::Dimension::dynamic(), ov::Dimension::dynamic(), ov::Dimension::dynamic()}, {{1, 10, 4}, {2, 2, 12}}}
|
||||
},
|
||||
// 4D
|
||||
{
|
||||
|
||||
@@ -313,11 +313,10 @@ TEST_P(can_fuse_reorder, surface_input_reorder) {
|
||||
std::tie(req_data_type, req_format) = GetParam();
|
||||
const auto reorder_prim_id = "surface_input_reorder_prim";
|
||||
|
||||
auto in_size = tensor{1, 1, 8, 8};
|
||||
auto weights_size = tensor{32, 1, 8, 8};
|
||||
auto in_layout = layout(data_types::u8, format::nv12, in_size);
|
||||
auto in_layout = layout({1, 8, 8, 1}, data_types::u8, format::nv12);
|
||||
// Set data type the same as input's data type
|
||||
auto reorder_layout = layout(data_types::u8, format::bfyx, in_size);
|
||||
auto reorder_layout = layout({1, 8, 8, 1}, data_types::u8, format::bfyx);
|
||||
|
||||
auto input_data = engine.allocate_memory({ in_layout });
|
||||
auto weights_dt = req_data_type == data_types::u8 ? data_types::i8 : req_data_type;
|
||||
@@ -328,9 +327,10 @@ TEST_P(can_fuse_reorder, surface_input_reorder) {
|
||||
auto surface_input_reorder_prim = reorder(reorder_prim_id, input_info("input"), reorder_layout);
|
||||
surface_input_reorder_prim.input_mem_type = reorder::memory_type::surface;
|
||||
auto conv_input_reorder_prim = reorder("reorder_conv", input_info(reorder_prim_id), req_format, req_data_type);
|
||||
auto conv_prim = cldnn::convolution("conv", input_info("reorder_conv"), "weights", "", 1, {1, 1}, {1, 1}, {0, 0}, {0, 0}, false);
|
||||
auto transpose = permute("permute", input_info("reorder_conv"), {0, 3, 1, 2});
|
||||
auto conv_prim = cldnn::convolution("conv", input_info("permute"), "weights", "", 1, {1, 1}, {1, 1}, {0, 0}, {0, 0}, false);
|
||||
|
||||
topology.add(input_layout_prim, weights_data_prim, surface_input_reorder_prim, conv_input_reorder_prim, conv_prim);
|
||||
topology.add(input_layout_prim, weights_data_prim, surface_input_reorder_prim, conv_input_reorder_prim, transpose, conv_prim);
|
||||
|
||||
ExecutionConfig cfg = get_test_default_config(engine);
|
||||
cfg.set_property(ov::intel_gpu::queue_type(QueueTypes::out_of_order));
|
||||
@@ -370,11 +370,10 @@ TEST_P(can_fuse_reorder, surface_input_reorder_batched) {
|
||||
const auto reorder_prim_id1 = "surface_input_reorder_prim1";
|
||||
const auto reorder_prim_id2 = "surface_input_reorder_prim2";
|
||||
|
||||
auto in_size = tensor{1, 1, 8, 8};
|
||||
auto weights_size = tensor{32, 1, 8, 8};
|
||||
auto in_layout = layout(data_types::u8, format::nv12, in_size);
|
||||
auto in_layout = layout({1, 8, 8, 1}, data_types::u8, format::nv12);
|
||||
// Set data type the same as input's data type
|
||||
auto reorder_layout = layout(data_types::u8, format::bfyx, in_size);
|
||||
auto reorder_layout = layout({1, 8, 8, 1}, data_types::u8, format::bfyx);
|
||||
|
||||
auto input_data = engine.allocate_memory({ in_layout });
|
||||
auto weights_dt = req_data_type == data_types::u8 ? data_types::i8 : req_data_type;
|
||||
@@ -389,10 +388,11 @@ TEST_P(can_fuse_reorder, surface_input_reorder_batched) {
|
||||
surface_input_reorder_prim2.input_mem_type = reorder::memory_type::surface;
|
||||
auto concat = concatenation("concat",{ input_info(reorder_prim_id1),input_info(reorder_prim_id2) }, 0);
|
||||
auto conv_input_reorder_prim = reorder("reorder_conv", input_info("concat"), req_format, req_data_type);
|
||||
auto conv_prim = cldnn::convolution("conv", input_info("reorder_conv"), "weights" , "", 1, {1, 1}, {1, 1}, {0, 0}, {0, 0}, false);
|
||||
auto transpose = permute("permute", input_info("reorder_conv"), {0, 3, 1, 2});
|
||||
auto conv_prim = cldnn::convolution("conv", input_info("permute"), "weights" , "", 1, {1, 1}, {1, 1}, {0, 0}, {0, 0}, false);
|
||||
|
||||
topology.add(input_layout_prim1, input_layout_prim2, weights_data_prim,
|
||||
surface_input_reorder_prim1, surface_input_reorder_prim2,
|
||||
surface_input_reorder_prim1, surface_input_reorder_prim2, transpose,
|
||||
conv_input_reorder_prim, concat, conv_prim);
|
||||
|
||||
ExecutionConfig cfg = get_test_default_config(engine);
|
||||
|
||||
@@ -14,259 +14,6 @@
|
||||
using namespace cldnn;
|
||||
using namespace ::tests;
|
||||
|
||||
typedef std::chrono::high_resolution_clock Time;
|
||||
typedef std::chrono::nanoseconds ns;
|
||||
typedef std::chrono::duration<double, std::ratio<1, 1000>> ms;
|
||||
typedef std::chrono::duration<float> fsec;
|
||||
|
||||
namespace {
|
||||
std::vector<unsigned char> createSampleData(int width, int height) {
|
||||
int data_size = width * (height + height / 2);
|
||||
auto data = std::vector<unsigned char>(data_size);
|
||||
srand((unsigned)time(0));
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
data[i * width + j] = (i + j) % 255;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < height / 2; i++) {
|
||||
for (int j = 0; j < width; j += 2) {
|
||||
data[width * height + i * width + j] = (i + j) % 255;
|
||||
data[width * height + i * width + j + 1] = (i + j) % 255;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
std::vector<float> createReferenceData(std::vector<unsigned char> data, int width, int height, cldnn::format format) {
|
||||
auto img = std::vector<float>(width * height * 3);
|
||||
for (int i = 0; i < height; i++) {
|
||||
for (int j = 0; j < width; j++) {
|
||||
int y_comp = data[i * width + j];
|
||||
int u_comp = data[width * height + i / 2 * width + ((j >> 1) << 1)];
|
||||
int v_comp = data[width * height + i / 2 * width + ((j >> 1) << 1) + 1];
|
||||
|
||||
float B = (1.164f * (float)(y_comp - 16) + 1.596f * (float)(v_comp - 128));
|
||||
float G = (1.164f * (float)(y_comp - 16) - 0.813f * (float)(v_comp - 128) - 0.391f * (u_comp - 128));
|
||||
float R = (1.164f * (float)(y_comp - 16) + 2.018f * (float)(u_comp - 128));
|
||||
|
||||
R = std::min(std::max(R, 0.f), 255.f);
|
||||
G = std::min(std::max(G, 0.f), 255.f);
|
||||
B = std::min(std::max(B, 0.f), 255.f);
|
||||
|
||||
if (format == cldnn::format::bfyx) {
|
||||
img[j + width * i] = R;
|
||||
img[j + width * i + width * height] = G;
|
||||
img[j + width * i + width * height * 2] = B;
|
||||
} else { //byxf
|
||||
img[3* width*i + 3 * j] = R;
|
||||
img[3 * width * i + 3 * j + 1] = G;
|
||||
img[3 * width*i + 3 * j + 2] = B;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
template <typename T>
|
||||
void start_cl_mem_check_2_inputs(bool is_caching_test) {
|
||||
device_query query(engine_types::ocl, runtime_types::ocl);
|
||||
auto devices = query.get_available_devices();
|
||||
ASSERT_TRUE(!devices.empty());
|
||||
|
||||
auto iter = devices.find(std::to_string(device_query::device_id));
|
||||
auto& device = iter != devices.end() ? iter->second : devices.begin()->second;
|
||||
auto engine = engine::create(engine_types::ocl, runtime_types::ocl, device);
|
||||
|
||||
auto ocl_instance = std::make_shared<OpenCL>(std::dynamic_pointer_cast<ocl::ocl_device>(device)->get_device());
|
||||
int width = 224;
|
||||
int height = 224;
|
||||
cl_int err;
|
||||
|
||||
if (!device->get_info().supports_image)
|
||||
GTEST_SKIP();
|
||||
|
||||
auto data = createSampleData(width, height);
|
||||
cl_image_format image_format;
|
||||
image_format.image_channel_order = CL_R;
|
||||
image_format.image_channel_data_type = CL_UNORM_INT8;
|
||||
cl_image_desc image_desc = { CL_MEM_OBJECT_IMAGE2D, (size_t)width, (size_t)height, 0,
|
||||
0, 0, 0, 0, 0, { nullptr } };
|
||||
|
||||
cl_mem nv12_image_plane_y = clCreateImage(ocl_instance->_context.get(), CL_MEM_READ_WRITE, &image_format, &image_desc, nullptr, &err);
|
||||
checkStatus(err, "Creating nv12 image plane_y failed");
|
||||
|
||||
image_format.image_channel_order = CL_RG;
|
||||
image_desc.image_width = width / 2;
|
||||
image_desc.image_height = height / 2;
|
||||
image_desc.image_depth = 1;
|
||||
|
||||
cl_mem nv12_image_plane_uv = clCreateImage(ocl_instance->_context.get(), CL_MEM_READ_WRITE, &image_format, &image_desc, nullptr, &err);
|
||||
checkStatus(err, "Creating nv12 image plane_uv failed");
|
||||
|
||||
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, true, origin, y_region, 0, 0, &data[0], 0, nullptr, nullptr);
|
||||
checkStatus(err, "Writing nv12 image plane_y failed");
|
||||
|
||||
err = clEnqueueWriteImage(ocl_instance->_queue.get(), nv12_image_plane_uv, true, origin, uv_region, 0, 0, &data[width * height], 0, nullptr, nullptr);
|
||||
checkStatus(err, "Writing nv12 image plane_uv failed");
|
||||
|
||||
auto input = input_layout("input", { data_types::i8, format::nv12, {1,1,height,width} });
|
||||
auto input2 = input_layout("input2", { data_types::i8, format::nv12, {1,1,height / 2,width / 2} });
|
||||
auto output_format = cldnn::format::byxf;
|
||||
layout output_layout(data_types::f32, output_format, { 1,3,height,width });
|
||||
auto input_memory = engine->share_image(input.layout, nv12_image_plane_y);
|
||||
auto input_memory2 = engine->share_image(input2.layout, nv12_image_plane_uv);
|
||||
|
||||
topology topology;
|
||||
topology.add(input);
|
||||
topology.add(input2);
|
||||
topology.add(reorder("reorder", input_info("input"), input_info("input2"), output_layout));
|
||||
|
||||
cldnn::network::ptr network = get_network(*engine, topology, get_test_default_config(*engine), get_test_stream_ptr(), is_caching_test);
|
||||
|
||||
network->set_input_data("input", input_memory);
|
||||
network->set_input_data("input2", input_memory2);
|
||||
|
||||
auto outputs = network->execute();
|
||||
|
||||
std::vector<T> reference_results = createReferenceData(data, width, height, output_format);
|
||||
auto output_prim = outputs.begin()->second.get_memory();
|
||||
cldnn::mem_lock<T> output_ptr(output_prim, get_test_stream());
|
||||
int size = width * height * 3;
|
||||
for (auto i = 0; i < size; i++) {
|
||||
ASSERT_NEAR(reference_results[i], output_ptr[i], 1.001f);
|
||||
}
|
||||
checkStatus(clReleaseMemObject(nv12_image_plane_uv), "clReleaseMemObject");
|
||||
checkStatus(clReleaseMemObject(nv12_image_plane_y), "clReleaseMemObject");
|
||||
}
|
||||
|
||||
TEST(cl_mem_check, check_2_inputs) {
|
||||
start_cl_mem_check_2_inputs<float>(false);
|
||||
}
|
||||
|
||||
TEST(export_import_cl_mem_check, check_2_inputs) {
|
||||
start_cl_mem_check_2_inputs<float>(true);
|
||||
}
|
||||
|
||||
TEST(cl_mem_check, check_input) {
|
||||
device_query query(engine_types::ocl, runtime_types::ocl);
|
||||
auto devices = query.get_available_devices();
|
||||
ASSERT_TRUE(!devices.empty());
|
||||
auto iter = devices.find(std::to_string(device_query::device_id));
|
||||
auto& device = iter != devices.end() ? iter->second : devices.begin()->second;
|
||||
auto engine = engine::create(engine_types::ocl, runtime_types::ocl, device);
|
||||
auto ocl_instance = std::make_shared<OpenCL>(std::dynamic_pointer_cast<ocl::ocl_device>(device)->get_device());
|
||||
|
||||
if (!device->get_info().supports_intel_planar_yuv)
|
||||
GTEST_SKIP();
|
||||
|
||||
int width = 224;
|
||||
int height = 224;
|
||||
cl_int err;
|
||||
|
||||
auto data = createSampleData(width, height);
|
||||
cl_image_format image_format;
|
||||
image_format.image_channel_order = CL_R;
|
||||
image_format.image_channel_data_type = CL_UNORM_INT8;
|
||||
cl_image_desc image_desc = { CL_MEM_OBJECT_IMAGE2D, (size_t)width, (size_t)height, 0,
|
||||
0, 0, 0, 0, 0, { nullptr } };
|
||||
|
||||
cl_mem nv12_image_plane_y = clCreateImage(ocl_instance->_context.get(), CL_MEM_READ_WRITE, &image_format, &image_desc, nullptr, &err);
|
||||
checkStatus(err, "Creating nv12 image plane_y failed");
|
||||
|
||||
image_format.image_channel_order = CL_RG;
|
||||
image_desc.image_width = width / 2;
|
||||
image_desc.image_height = height / 2;
|
||||
|
||||
cl_mem nv12_image_plane_uv = clCreateImage(ocl_instance->_context.get(), CL_MEM_READ_WRITE, &image_format, &image_desc, nullptr, &err);
|
||||
checkStatus(err, "Creating nv12 image plane_uv failed");
|
||||
|
||||
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, true, origin, y_region, 0, 0, &data[0], 0, nullptr, nullptr);
|
||||
checkStatus(err, "Writing nv12 image plane_y failed");
|
||||
|
||||
err = clEnqueueWriteImage(ocl_instance->_queue.get(), nv12_image_plane_uv, true, origin, uv_region, 0, 0, &data[width * height], 0, nullptr, nullptr);
|
||||
checkStatus(err, "Writing nv12 image plane_uv failed");
|
||||
|
||||
image_format.image_channel_order = CL_NV12_INTEL;
|
||||
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;
|
||||
image_desc.image_array_size = 0;
|
||||
image_desc.image_row_pitch = 0;
|
||||
image_desc.image_slice_pitch = 0;
|
||||
image_desc.num_mip_levels = 0;
|
||||
image_desc.num_samples = 0;
|
||||
image_desc.buffer = NULL;
|
||||
|
||||
cl_mem img = clCreateImage(ocl_instance->_context.get(), CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS | CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL,
|
||||
&image_format, &image_desc, NULL, &err);
|
||||
checkStatus(err, "Creating nv12 image failed");
|
||||
|
||||
image_desc.image_width = 0;
|
||||
image_desc.image_height = 0;
|
||||
image_desc.buffer = img;
|
||||
image_desc.image_depth = 0;
|
||||
image_format.image_channel_order = CL_R;
|
||||
|
||||
cl_mem img_y = clCreateImage(ocl_instance->_context.get(), CL_MEM_READ_WRITE, &image_format, &image_desc, nullptr, &err);
|
||||
checkStatus(err, "Creating nv12 image plane_y failed");
|
||||
|
||||
image_desc.image_depth = 1;
|
||||
image_format.image_channel_order = CL_RG;
|
||||
cl_mem img_uv = clCreateImage(ocl_instance->_context.get(), CL_MEM_READ_WRITE, &image_format, &image_desc, nullptr, &err);
|
||||
checkStatus(err, "Creating nv12 image plane_uv failed");
|
||||
|
||||
size_t regionY[] = { (size_t)width, (size_t)height, 1 };
|
||||
size_t regionUV[] = { (size_t)width / 2, (size_t)height / 2, 1 };
|
||||
|
||||
err = clEnqueueCopyImage(ocl_instance->_queue.get(), nv12_image_plane_y, img_y, origin, origin, regionY, 0, 0, 0);
|
||||
checkStatus(err, "clEnqueueCopyImage");
|
||||
|
||||
cl_event event_out;
|
||||
err = clEnqueueCopyImage(ocl_instance->_queue.get(), nv12_image_plane_uv, img_uv, origin, origin, regionUV, 0, 0, &event_out);
|
||||
checkStatus(err, "clEnqueueCopyImage");
|
||||
|
||||
checkStatus(clReleaseMemObject(nv12_image_plane_uv), "clReleaseMemObject");
|
||||
checkStatus(clReleaseMemObject(nv12_image_plane_y), "clReleaseMemObject");
|
||||
|
||||
auto input = input_layout("input", { data_types::i8, format::nv12, {1,1,height,width} });
|
||||
auto output_format = cldnn::format::byxf;
|
||||
layout output_layout(data_types::f32, output_format, { 1,3,height,width });
|
||||
auto input_memory = engine->share_image(input.layout, img);
|
||||
|
||||
topology topology;
|
||||
|
||||
topology.add(input);
|
||||
topology.add(reorder("reorder", input_info("input"), output_layout));
|
||||
|
||||
network network(*engine, topology, get_test_default_config(*engine));
|
||||
network.set_input_data("input", input_memory);
|
||||
|
||||
auto outputs = network.execute();
|
||||
|
||||
std::vector<float> reference_results = createReferenceData(data, width, height, output_format);
|
||||
auto output_prim = outputs.begin()->second.get_memory();
|
||||
cldnn::mem_lock<float> output_ptr(output_prim, get_test_stream());
|
||||
int size = width * height * 3;
|
||||
for (auto i = 0; i < size; i++) {
|
||||
ASSERT_NEAR(reference_results[i], output_ptr[i], 1.001f);
|
||||
}
|
||||
checkStatus(clReleaseMemObject(img), "clReleaseMemObject");
|
||||
}
|
||||
|
||||
TEST(cl_mem_check, check_write_access_type) {
|
||||
device_query query(engine_types::ocl, runtime_types::ocl);
|
||||
auto devices = query.get_available_devices();
|
||||
@@ -285,7 +32,7 @@ TEST(cl_mem_check, check_write_access_type) {
|
||||
std::vector<float> src_buffer(values_count);
|
||||
std::iota(src_buffer.begin(), src_buffer.end(), 0.0f);
|
||||
|
||||
cldnn::layout linear_layout = cldnn::layout(cldnn::data_types::f32, cldnn::format::bfyx, cldnn::tensor(1, 1, int32_t(values_count), 1));
|
||||
cldnn::layout linear_layout{{ov::Dimension(values_count)}, cldnn::data_types::f32, cldnn::format::bfyx};
|
||||
auto cldnn_mem_src = engine->allocate_memory(linear_layout, cldnn::allocation_type::cl_mem);
|
||||
{
|
||||
cldnn::mem_lock<float, cldnn::mem_lock_type::write> lock(cldnn_mem_src, *stream);
|
||||
@@ -323,7 +70,7 @@ TEST(cl_mem_check, check_read_access_type) {
|
||||
std::vector<float> src_buffer(values_count);
|
||||
std::iota(src_buffer.begin(), src_buffer.end(), 0.0f);
|
||||
|
||||
cldnn::layout linear_layout = cldnn::layout(cldnn::data_types::f32, cldnn::format::bfyx, cldnn::tensor(1, 1, int32_t(values_count), 1));
|
||||
cldnn::layout linear_layout{{ov::Dimension(values_count)}, cldnn::data_types::f32, cldnn::format::bfyx};
|
||||
auto cldnn_mem_src = engine->allocate_memory(linear_layout, cldnn::allocation_type::cl_mem);
|
||||
{
|
||||
cldnn::mem_lock<float, cldnn::mem_lock_type::write> lock(cldnn_mem_src, *stream);
|
||||
|
||||
@@ -66,8 +66,8 @@ TEST(convert_color, nv12_to_rgb_two_planes_buffer_fp32) {
|
||||
int width = 224;
|
||||
int height = 448;
|
||||
|
||||
auto input_y = engine.allocate_memory({ data_types::f32, format::byxf, { 1, 1, width, height } });
|
||||
auto input_uv = engine.allocate_memory({ data_types::f32, format::byxf, { 1, 2, width / 2 , height / 2 } });
|
||||
auto input_y = engine.allocate_memory({ { 1, height, width, 1 }, data_types::f32, format::bfyx });
|
||||
auto input_uv = engine.allocate_memory({ { 1, height / 2 , width / 2, 2 }, data_types::f32, format::bfyx});
|
||||
|
||||
std::vector<float> input_y_data = rg.generate_random_1d<float>(width * height, 0, 255);
|
||||
std::vector<float> input_uv_data = rg.generate_random_1d<float>(width * height / 2, 0, 255);
|
||||
@@ -75,13 +75,14 @@ TEST(convert_color, nv12_to_rgb_two_planes_buffer_fp32) {
|
||||
set_values(input_y, input_y_data);
|
||||
set_values(input_uv, input_uv_data);
|
||||
|
||||
layout output_layout(data_types::f32, cldnn::format::byxf, { 1, 3, width, height });
|
||||
|
||||
topology topology;
|
||||
topology.add(input_layout("input_y", input_y->get_layout()));
|
||||
topology.add(input_layout("input_uv", input_uv->get_layout()));
|
||||
topology.add(convert_color("convert_color", { input_info("input_y"), input_info("input_uv") }, cldnn::convert_color::color_format::NV12, cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::buffer, output_layout));
|
||||
topology.add(convert_color("convert_color",
|
||||
{ input_info("input_y"), input_info("input_uv") },
|
||||
cldnn::convert_color::color_format::NV12,
|
||||
cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::buffer));
|
||||
|
||||
network network(engine, topology, get_test_default_config(engine));
|
||||
network.set_input_data("input_y", input_y);
|
||||
@@ -106,8 +107,8 @@ TEST(convert_color, nv12_to_bgr_two_planes_buffer_fp32) {
|
||||
int width = 224;
|
||||
int height = 224;
|
||||
|
||||
auto input_y = engine.allocate_memory({ data_types::f32, format::byxf, { 1, 1, width, height } });
|
||||
auto input_uv = engine.allocate_memory({ data_types::f32, format::byxf, { 1, 2, width / 2 , height / 2 } });
|
||||
auto input_y = engine.allocate_memory({ { 1, height, width, 1 }, data_types::f32, format::bfyx });
|
||||
auto input_uv = engine.allocate_memory({ { 1, height / 2 , width / 2, 2 }, data_types::f32, format::bfyx});
|
||||
|
||||
std::vector<float> input_y_data = rg.generate_random_1d<float>(width * height, 0, 255);
|
||||
std::vector<float> input_uv_data = rg.generate_random_1d<float>(width * height / 2, 0, 255);
|
||||
@@ -115,13 +116,14 @@ TEST(convert_color, nv12_to_bgr_two_planes_buffer_fp32) {
|
||||
set_values(input_y, input_y_data);
|
||||
set_values(input_uv, input_uv_data);
|
||||
|
||||
layout output_layout(data_types::f32, cldnn::format::byxf, { 1, 3, width, height });
|
||||
|
||||
topology topology;
|
||||
topology.add(input_layout("input_y", input_y->get_layout()));
|
||||
topology.add(input_layout("input_uv", input_uv->get_layout()));
|
||||
topology.add(convert_color("convert_color", { input_info("input_y"), input_info("input_uv") }, cldnn::convert_color::color_format::NV12, cldnn::convert_color::color_format::BGR,
|
||||
cldnn::convert_color::memory_type::buffer, output_layout));
|
||||
topology.add(convert_color("convert_color",
|
||||
{ input_info("input_y"), input_info("input_uv") },
|
||||
cldnn::convert_color::color_format::NV12,
|
||||
cldnn::convert_color::color_format::BGR,
|
||||
cldnn::convert_color::memory_type::buffer));
|
||||
|
||||
network network(engine, topology, get_test_default_config(engine));
|
||||
network.set_input_data("input_y", input_y);
|
||||
@@ -147,8 +149,8 @@ TEST(convert_color, nv12_to_rgb_two_planes_buffer_u8) {
|
||||
int width = 224;
|
||||
int height = 224;
|
||||
|
||||
auto input_y = engine.allocate_memory({ data_types::u8, format::byxf, { 1, 1, width, height } });
|
||||
auto input_uv = engine.allocate_memory({ data_types::u8, format::byxf, { 1, 2, width / 2 , height / 2 } });
|
||||
auto input_y = engine.allocate_memory({ { 1, height, width, 1 }, data_types::u8, format::bfyx });
|
||||
auto input_uv = engine.allocate_memory({ { 1, height / 2 , width / 2, 2 }, data_types::u8, format::bfyx});
|
||||
|
||||
std::vector<uint8_t> input_y_data = rg.generate_random_1d<uint8_t>(width * height, 0, 255);
|
||||
std::vector<uint8_t> input_uv_data = rg.generate_random_1d<uint8_t>(width * height / 2, 0, 255);
|
||||
@@ -156,13 +158,14 @@ TEST(convert_color, nv12_to_rgb_two_planes_buffer_u8) {
|
||||
set_values(input_y, input_y_data);
|
||||
set_values(input_uv, input_uv_data);
|
||||
|
||||
layout output_layout(data_types::u8, cldnn::format::byxf, { 1, 3, width, height });
|
||||
|
||||
topology topology;
|
||||
topology.add(input_layout("input_y", input_y->get_layout()));
|
||||
topology.add(input_layout("input_uv", input_uv->get_layout()));
|
||||
topology.add(convert_color("convert_color", { input_info("input_y"), input_info("input_uv") }, cldnn::convert_color::color_format::NV12, cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::buffer, output_layout));
|
||||
topology.add(convert_color("convert_color",
|
||||
{ input_info("input_y"), input_info("input_uv") },
|
||||
cldnn::convert_color::color_format::NV12,
|
||||
cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::buffer));
|
||||
|
||||
network network(engine, topology, get_test_default_config(engine));
|
||||
network.set_input_data("input_y", input_y);
|
||||
@@ -188,8 +191,8 @@ TEST(convert_color, nv12_to_rgb_two_planes_buffer_fp16) {
|
||||
int width = 224;
|
||||
int height = 224;
|
||||
|
||||
auto input_y = engine.allocate_memory({ data_types::f16, format::byxf, { 1, 1, width, height } });
|
||||
auto input_uv = engine.allocate_memory({ data_types::f16, format::byxf, { 1, 2, width / 2 , height / 2 } });
|
||||
auto input_y = engine.allocate_memory({ { 1, height, width, 1 }, data_types::f16, format::bfyx });
|
||||
auto input_uv = engine.allocate_memory({ { 1, height / 2 , width / 2, 2 }, data_types::f16, format::bfyx});
|
||||
|
||||
std::vector<FLOAT16> input_y_data = rg.generate_random_1d<FLOAT16>(width * height, 0, 255);
|
||||
std::vector<FLOAT16> input_uv_data = rg.generate_random_1d<FLOAT16>(width * height / 2, 0, 255);
|
||||
@@ -197,13 +200,14 @@ TEST(convert_color, nv12_to_rgb_two_planes_buffer_fp16) {
|
||||
set_values(input_y, input_y_data);
|
||||
set_values(input_uv, input_uv_data);
|
||||
|
||||
layout output_layout(data_types::f16, cldnn::format::byxf, { 1, 3, width, height });
|
||||
|
||||
topology topology;
|
||||
topology.add(input_layout("input_y", input_y->get_layout()));
|
||||
topology.add(input_layout("input_uv", input_uv->get_layout()));
|
||||
topology.add(convert_color("convert_color", { input_info("input_y"), input_info("input_uv") }, cldnn::convert_color::color_format::NV12, cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::buffer, output_layout));
|
||||
topology.add(convert_color("convert_color",
|
||||
{ input_info("input_y"), input_info("input_uv") },
|
||||
cldnn::convert_color::color_format::NV12,
|
||||
cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::buffer));
|
||||
|
||||
network network(engine, topology, get_test_default_config(engine));
|
||||
network.set_input_data("input_y", input_y);
|
||||
@@ -231,18 +235,19 @@ TEST(convert_color, nv12_to_rgb_single_plane_buffer_fp32) {
|
||||
int height = 448;
|
||||
int input_height = height + height / 2;
|
||||
|
||||
auto input = engine.allocate_memory({ data_types::f32, format::byxf, { 1, 1, width, input_height } });
|
||||
auto input = engine.allocate_memory({{ 1, input_height, width, 1 }, data_types::f32, format::bfyx});
|
||||
|
||||
int data_size = width * (height + height / 2);
|
||||
std::vector<float> input_data = rg.generate_random_1d<float>(data_size, 0, 255);
|
||||
set_values(input, input_data);
|
||||
|
||||
layout output_layout(data_types::f32, cldnn::format::byxf, { 1, 3, width, height });
|
||||
|
||||
topology topology;
|
||||
topology.add(input_layout("input", input->get_layout()));
|
||||
topology.add(convert_color("convert_color", { input_info("input") }, cldnn::convert_color::color_format::NV12, cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::buffer, output_layout));
|
||||
topology.add(convert_color("convert_color",
|
||||
{ input_info("input") },
|
||||
cldnn::convert_color::color_format::NV12,
|
||||
cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::buffer));
|
||||
|
||||
network network(engine, topology, get_test_default_config(engine));
|
||||
network.set_input_data("input", input);
|
||||
@@ -268,18 +273,19 @@ TEST(convert_color, nv12_to_rgb_single_plane_buffer_u8) {
|
||||
int height = 448;
|
||||
int input_height = height + height / 2;
|
||||
|
||||
auto input = engine.allocate_memory({ data_types::u8, format::byxf, { 1, 1, width, input_height } });
|
||||
auto input = engine.allocate_memory({{ 1, input_height, width, 1 }, data_types::u8, format::bfyx});
|
||||
|
||||
int data_size = width * (height + height / 2);
|
||||
std::vector<uint8_t> input_data = rg.generate_random_1d<uint8_t>(data_size, 0, 255);
|
||||
set_values(input, input_data);
|
||||
|
||||
layout output_layout(data_types::u8, cldnn::format::byxf, { 1, 3, width, height });
|
||||
|
||||
topology topology;
|
||||
topology.add(input_layout("input", input->get_layout()));
|
||||
topology.add(convert_color("convert_color", { input_info("input") }, cldnn::convert_color::color_format::NV12, cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::buffer, output_layout));
|
||||
topology.add(convert_color("convert_color",
|
||||
{ input_info("input") },
|
||||
cldnn::convert_color::color_format::NV12,
|
||||
cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::buffer));
|
||||
|
||||
network network(engine, topology, get_test_default_config(engine));
|
||||
network.set_input_data("input", input);
|
||||
@@ -346,18 +352,19 @@ TEST(convert_color, nv12_to_rgb_two_planes_surface_u8) {
|
||||
err = clEnqueueWriteImage(ocl_instance->_queue.get(), nv12_image_plane_uv, true, origin, uv_region, 0, 0, &data[width * height], 0, nullptr, nullptr);
|
||||
checkStatus(err, "Writing nv12 image plane_uv failed");
|
||||
|
||||
auto input = input_layout("input", { data_types::u8, format::nv12, { 1, 1, width, height } });
|
||||
auto input2 = input_layout("input2", { data_types::u8, format::nv12, { 1, 2, width / 2, height / 2} });
|
||||
auto output_format = cldnn::format::byxf;
|
||||
layout output_layout(data_types::f32, output_format, { 1, 3, width, height });
|
||||
auto input = input_layout("input", { { 1, height, width, 1} , data_types::u8, format::nv12 });
|
||||
auto input2 = input_layout("input2", { { 1, height / 2, width / 2, 2}, data_types::u8, format::nv12 });
|
||||
auto input_memory = engine->share_image(input.layout, nv12_image_plane_y);
|
||||
auto input_memory2 = engine->share_image(input2.layout, nv12_image_plane_uv);
|
||||
|
||||
topology topology;
|
||||
topology.add(input);
|
||||
topology.add(input2);
|
||||
topology.add(convert_color("convert_color", { input_info("input"), input_info("input2") }, cldnn::convert_color::color_format::NV12, cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::image, output_layout));
|
||||
topology.add(convert_color("convert_color",
|
||||
{ input_info("input"), input_info("input2") },
|
||||
cldnn::convert_color::color_format::NV12,
|
||||
cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::image));
|
||||
|
||||
network network(*engine, topology, get_test_default_config(*engine));
|
||||
network.set_input_data("input", input_memory);
|
||||
@@ -365,14 +372,14 @@ TEST(convert_color, nv12_to_rgb_two_planes_surface_u8) {
|
||||
|
||||
auto outputs = network.execute();
|
||||
|
||||
std::vector<float> reference_results(width * height * 3);
|
||||
createReferenceDataNV12<uint8_t, float>(data.data(), data.data() + height * width, reference_results.data(),
|
||||
1, height, width, height * width, height * width / 2, true);
|
||||
std::vector<uint8_t> reference_results(width * height * 3);
|
||||
createReferenceDataNV12<uint8_t, uint8_t>(data.data(), data.data() + height * width, reference_results.data(),
|
||||
1, height, width, height * width, height * width / 2, true);
|
||||
|
||||
auto output_prim = outputs.begin()->second.get_memory();
|
||||
cldnn::mem_lock<float> output_ptr(output_prim, get_test_stream());
|
||||
cldnn::mem_lock<uint8_t> output_ptr(output_prim, get_test_stream());
|
||||
for (size_t i = 0; i < reference_results.size(); i++) {
|
||||
ASSERT_NEAR(reference_results[i], output_ptr[i], 1.001f);
|
||||
ASSERT_EQ(reference_results[i], output_ptr[i]);
|
||||
}
|
||||
checkStatus(clReleaseMemObject(nv12_image_plane_uv), "clReleaseMemObject");
|
||||
checkStatus(clReleaseMemObject(nv12_image_plane_y), "clReleaseMemObject");
|
||||
@@ -415,29 +422,30 @@ TEST(convert_color, nv12_to_rgb_single_plane_surface_u8) {
|
||||
err = clEnqueueWriteImage(ocl_instance->_queue.get(), nv12_image, true, origin, y_region, 0, 0, &input_data[0], 0, nullptr, nullptr);
|
||||
checkStatus(err, "Writing nv12 image failed");
|
||||
|
||||
auto input = input_layout("input", { data_types::u8, format::nv12, { 1, 1, width, input_height } });
|
||||
auto output_format = cldnn::format::byxf;
|
||||
layout output_layout(data_types::f32, output_format, { 1, 3, width, height });
|
||||
auto input = input_layout("input", {{ 1, input_height, width, 1 }, data_types::u8, format::nv12});
|
||||
auto input_memory = engine->share_image(input.layout, nv12_image);
|
||||
|
||||
topology topology;
|
||||
topology.add(input);
|
||||
topology.add(convert_color("convert_color", { input_info("input") }, cldnn::convert_color::color_format::NV12, cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::image, output_layout));
|
||||
topology.add(convert_color("convert_color",
|
||||
{ input_info("input") },
|
||||
cldnn::convert_color::color_format::NV12,
|
||||
cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::image));
|
||||
|
||||
network network(*engine, topology, get_test_default_config(*engine));
|
||||
network.set_input_data("input", input_memory);
|
||||
|
||||
auto outputs = network.execute();
|
||||
|
||||
std::vector<float> reference_results(width * height * 3);
|
||||
createReferenceDataNV12<uint8_t, float>(input_data.data(), input_data.data() + height * width, reference_results.data(),
|
||||
std::vector<uint8_t> reference_results(width * height * 3);
|
||||
createReferenceDataNV12<uint8_t, uint8_t>(input_data.data(), input_data.data() + height * width, reference_results.data(),
|
||||
1, height, width, input_height * width, input_height * width, true);
|
||||
|
||||
auto output_prim = outputs.begin()->second.get_memory();
|
||||
cldnn::mem_lock<float> output_ptr(output_prim, get_test_stream());
|
||||
cldnn::mem_lock<uint8_t> output_ptr(output_prim, get_test_stream());
|
||||
for (size_t i = 0; i < reference_results.size(); i++) {
|
||||
ASSERT_NEAR(reference_results[i], output_ptr[i], 1.001f);
|
||||
ASSERT_EQ(reference_results[i], output_ptr[i]);
|
||||
}
|
||||
checkStatus(clReleaseMemObject(nv12_image), "clReleaseMemObject");
|
||||
}
|
||||
@@ -498,9 +506,9 @@ TEST(convert_color, i420_to_rgb_three_planes_buffer_fp32) {
|
||||
int width = 224;
|
||||
int height = 448;
|
||||
|
||||
auto input_y = engine.allocate_memory({ data_types::f32, format::byxf, { 1, 1, width, height } });
|
||||
auto input_u = engine.allocate_memory({ data_types::f32, format::byxf, { 1, 1, width / 2 , height / 2 } });
|
||||
auto input_v = engine.allocate_memory({ data_types::f32, format::byxf, { 1, 1, width / 2 , height / 2 } });
|
||||
auto input_y = engine.allocate_memory({ { 1, height, width, 1 }, data_types::f32, format::bfyx });
|
||||
auto input_u = engine.allocate_memory({ { 1, height / 2 , width / 2, 1 }, data_types::f32, format::bfyx });
|
||||
auto input_v = engine.allocate_memory({ { 1, height / 2 , width / 2, 1 }, data_types::f32, format::bfyx });
|
||||
|
||||
std::vector<float> input_y_data = rg.generate_random_1d<float>(width * height, 0, 255);
|
||||
std::vector<float> input_u_data = rg.generate_random_1d<float>(width * height / 4, 0, 255);
|
||||
@@ -510,14 +518,15 @@ TEST(convert_color, i420_to_rgb_three_planes_buffer_fp32) {
|
||||
set_values(input_u, input_u_data);
|
||||
set_values(input_v, input_v_data);
|
||||
|
||||
layout output_layout(data_types::f32, cldnn::format::byxf, { 1, 3, width, height });
|
||||
|
||||
topology topology;
|
||||
topology.add(input_layout("input_y", input_y->get_layout()));
|
||||
topology.add(input_layout("input_u", input_u->get_layout()));
|
||||
topology.add(input_layout("input_v", input_v->get_layout()));
|
||||
topology.add(convert_color("convert_color", { input_info("input_y"), input_info("input_u"), input_info("input_v") }, cldnn::convert_color::color_format::I420, cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::buffer, output_layout));
|
||||
topology.add(convert_color("convert_color",
|
||||
{ input_info("input_y"), input_info("input_u"), input_info("input_v") },
|
||||
cldnn::convert_color::color_format::I420,
|
||||
cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::buffer));
|
||||
|
||||
network network(engine, topology, get_test_default_config(engine));
|
||||
network.set_input_data("input_y", input_y);
|
||||
@@ -590,11 +599,9 @@ void test_convert_color_i420_to_rgb_three_planes_surface_u8(bool is_caching_test
|
||||
err = clEnqueueWriteImage(ocl_instance->_queue.get(), i420_image_plane_v, true, origin, uv_region, 0, 0, &data[width * (height + height / 4)], 0, nullptr, nullptr);
|
||||
checkStatus(err, "Writing i420 image plane_v failed");
|
||||
|
||||
auto input = input_layout("input", { data_types::u8, format::nv12, { 1, 1, width, height } });
|
||||
auto input2 = input_layout("input2", { data_types::u8, format::nv12, { 1, 1, width / 2, height / 2 } });
|
||||
auto input3 = input_layout("input3", { data_types::u8, format::nv12, { 1, 1, width / 2, height / 2 } });
|
||||
auto output_format = cldnn::format::byxf;
|
||||
layout output_layout(data_types::f32, output_format, { 1, 3, width, height });
|
||||
auto input = input_layout("input", { { 1, height, width, 1 }, data_types::u8, format::nv12, });
|
||||
auto input2 = input_layout("input2", { { 1, height / 2, width / 2, 1 }, data_types::u8, format::nv12 });
|
||||
auto input3 = input_layout("input3", { { 1, height / 2, width / 2, 1 }, data_types::u8, format::nv12 });
|
||||
|
||||
auto input_memory = engine->share_image(input.layout, i420_image_plane_y);
|
||||
auto input_memory2 = engine->share_image(input2.layout, i420_image_plane_u);
|
||||
@@ -604,8 +611,11 @@ void test_convert_color_i420_to_rgb_three_planes_surface_u8(bool is_caching_test
|
||||
topology.add(input);
|
||||
topology.add(input2);
|
||||
topology.add(input3);
|
||||
topology.add(convert_color("convert_color", { input_info("input"), input_info("input2"), input_info("input3") }, cldnn::convert_color::color_format::I420, cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::image, output_layout));
|
||||
topology.add(convert_color("convert_color",
|
||||
{ input_info("input"), input_info("input2"), input_info("input3") },
|
||||
cldnn::convert_color::color_format::I420,
|
||||
cldnn::convert_color::color_format::RGB,
|
||||
cldnn::convert_color::memory_type::image));
|
||||
|
||||
cldnn::network::ptr network = get_network(*engine, topology, get_test_default_config(*engine), get_test_stream_ptr(), is_caching_test);
|
||||
|
||||
@@ -615,14 +625,14 @@ void test_convert_color_i420_to_rgb_three_planes_surface_u8(bool is_caching_test
|
||||
|
||||
auto outputs = network->execute();
|
||||
|
||||
std::vector<float> reference_results(width * height * 3);
|
||||
createReferenceDataI420<T, float>(data.data(), data.data() + height * width, data.data() + width * (height + height / 4), reference_results.data(),
|
||||
std::vector<uint8_t> reference_results(width * height * 3);
|
||||
createReferenceDataI420<T, uint8_t>(data.data(), data.data() + height * width, data.data() + width * (height + height / 4), reference_results.data(),
|
||||
1, height, width, height * width, height * width / 2, true);
|
||||
|
||||
auto output_prim = outputs.begin()->second.get_memory();
|
||||
cldnn::mem_lock<float> output_ptr(output_prim, get_test_stream());
|
||||
cldnn::mem_lock<uint8_t> output_ptr(output_prim, get_test_stream());
|
||||
for (size_t i = 0; i < reference_results.size(); i++) {
|
||||
ASSERT_NEAR(reference_results[i], output_ptr[i], 1.001f);
|
||||
ASSERT_EQ(reference_results[i], output_ptr[i]) << " i = " << i;
|
||||
}
|
||||
checkStatus(clReleaseMemObject(i420_image_plane_y), "clReleaseMemObject");
|
||||
checkStatus(clReleaseMemObject(i420_image_plane_u), "clReleaseMemObject");
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
// Copyright (C) 2018-2022 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "test_utils.h"
|
||||
#include "intel_gpu/graph/serialization/binary_buffer.hpp"
|
||||
#include "intel_gpu/graph/serialization/string_serializer.hpp"
|
||||
#include "intel_gpu/graph/serialization/utils.hpp"
|
||||
|
||||
using namespace cldnn;
|
||||
using namespace ::tests;
|
||||
|
||||
struct ie_layout_serialization_test : testing::TestWithParam<InferenceEngine::Layout> {
|
||||
void run_test() {
|
||||
InferenceEngine::Layout test_layout = GetParam();
|
||||
|
||||
membuf mem_buf;
|
||||
{
|
||||
std::ostream out_mem(&mem_buf);
|
||||
BinaryOutputBuffer ob = BinaryOutputBuffer(out_mem);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << test_layout;
|
||||
ob << ss.str();
|
||||
}
|
||||
{
|
||||
std::istream in_mem(&mem_buf);
|
||||
BinaryInputBuffer ib = BinaryInputBuffer(in_mem, get_test_engine());
|
||||
|
||||
std::string str_layout;
|
||||
ib >> str_layout;
|
||||
EXPECT_EQ(cldnn::serial_util::layout_from_string(str_layout), test_layout);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(ie_layout_serialization_test, basic) {
|
||||
run_test();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
gpu_serialization,
|
||||
ie_layout_serialization_test,
|
||||
testing::Values(InferenceEngine::Layout::ANY,
|
||||
InferenceEngine::Layout::NCHW,
|
||||
InferenceEngine::Layout::NHWC,
|
||||
InferenceEngine::Layout::NCDHW,
|
||||
InferenceEngine::Layout::NDHWC,
|
||||
InferenceEngine::Layout::OIHW,
|
||||
InferenceEngine::Layout::GOIHW,
|
||||
InferenceEngine::Layout::OIDHW,
|
||||
InferenceEngine::Layout::GOIDHW,
|
||||
InferenceEngine::Layout::SCALAR,
|
||||
InferenceEngine::Layout::C,
|
||||
InferenceEngine::Layout::CHW,
|
||||
InferenceEngine::Layout::HWC,
|
||||
InferenceEngine::Layout::HW,
|
||||
InferenceEngine::Layout::NC,
|
||||
InferenceEngine::Layout::CN,
|
||||
InferenceEngine::Layout::BLOCKED)
|
||||
);
|
||||
@@ -26,7 +26,7 @@ void create_plugin(std::shared_ptr<ov::IPlugin>& plugin);
|
||||
*
|
||||
* @return Original remote context
|
||||
*/
|
||||
const ov::SoPtr<ov::IRemoteContext>& get_hardware_context(const ov::SoPtr<ov::IRemoteContext>& context);
|
||||
ov::SoPtr<ov::IRemoteContext> get_hardware_context(const ov::SoPtr<ov::IRemoteContext>& context);
|
||||
|
||||
/**
|
||||
* @brief Get wrapped remote tensor
|
||||
@@ -35,7 +35,7 @@ const ov::SoPtr<ov::IRemoteContext>& get_hardware_context(const ov::SoPtr<ov::IR
|
||||
*
|
||||
* @return Original remote tensor
|
||||
*/
|
||||
const ov::SoPtr<ov::ITensor>& get_hardware_tensor(const ov::SoPtr<ov::ITensor>& tensor);
|
||||
ov::SoPtr<ov::ITensor> get_hardware_tensor(const ov::SoPtr<ov::ITensor>& tensor, bool unwrap = false);
|
||||
|
||||
} // namespace proxy
|
||||
} // namespace ov
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <memory>
|
||||
#include <openvino/runtime/iremote_tensor.hpp>
|
||||
|
||||
#include "openvino/proxy/plugin.hpp"
|
||||
#include "openvino/runtime/itensor.hpp"
|
||||
#include "openvino/runtime/make_tensor.hpp"
|
||||
#include "openvino/runtime/remote_context.hpp"
|
||||
@@ -57,7 +58,7 @@ ov::SoPtr<ov::ITensor> ov::proxy::InferRequest::get_tensor(const ov::Output<cons
|
||||
}
|
||||
|
||||
void ov::proxy::InferRequest::set_tensor(const ov::Output<const ov::Node>& port, const ov::SoPtr<ov::ITensor>& tensor) {
|
||||
m_infer_request->set_tensor(port, tensor);
|
||||
m_infer_request->set_tensor(port, ov::proxy::get_hardware_tensor(tensor, true));
|
||||
}
|
||||
|
||||
std::vector<ov::SoPtr<ov::ITensor>> ov::proxy::InferRequest::get_tensors(const ov::Output<const ov::Node>& port) const {
|
||||
@@ -75,7 +76,11 @@ std::vector<ov::SoPtr<ov::ITensor>> ov::proxy::InferRequest::get_tensors(const o
|
||||
|
||||
void ov::proxy::InferRequest::set_tensors(const ov::Output<const ov::Node>& port,
|
||||
const std::vector<ov::SoPtr<ov::ITensor>>& tensors) {
|
||||
return m_infer_request->set_tensors(port, tensors);
|
||||
std::vector<ov::SoPtr<ov::ITensor>> hw_tensors;
|
||||
for (auto& tensor : tensors) {
|
||||
hw_tensors.push_back(ov::proxy::get_hardware_tensor(tensor, true));
|
||||
}
|
||||
return m_infer_request->set_tensors(port, hw_tensors);
|
||||
}
|
||||
|
||||
std::vector<ov::SoPtr<ov::IVariableState>> ov::proxy::InferRequest::query_state() const {
|
||||
|
||||
@@ -75,6 +75,6 @@ const ov::SoPtr<ov::IRemoteContext>& ov::proxy::RemoteContext::get_hardware_cont
|
||||
return context;
|
||||
}
|
||||
|
||||
const ov::SoPtr<ov::IRemoteContext>& ov::proxy::get_hardware_context(const ov::SoPtr<ov::IRemoteContext>& context) {
|
||||
ov::SoPtr<ov::IRemoteContext> ov::proxy::get_hardware_context(const ov::SoPtr<ov::IRemoteContext>& context) {
|
||||
return ov::proxy::RemoteContext::get_hardware_context(context);
|
||||
}
|
||||
@@ -7,6 +7,10 @@
|
||||
#include <memory>
|
||||
|
||||
#include "openvino/proxy/plugin.hpp"
|
||||
#include "openvino/runtime/itensor.hpp"
|
||||
#include "openvino/runtime/make_tensor.hpp"
|
||||
#include "openvino/runtime/so_ptr.hpp"
|
||||
#include "remote_utils.hpp"
|
||||
|
||||
namespace {
|
||||
std::shared_ptr<ov::IRemoteTensor> cast_tensor(const ov::SoPtr<ov::ITensor>& tensor) {
|
||||
@@ -59,12 +63,23 @@ const ov::Strides& ov::proxy::RemoteTensor::get_strides() const {
|
||||
return m_tensor->get_strides();
|
||||
}
|
||||
|
||||
const ov::SoPtr<ov::ITensor>& ov::proxy::RemoteTensor::get_hardware_tensor(const ov::SoPtr<ov::ITensor>& tensor) {
|
||||
ov::SoPtr<ov::ITensor> ov::proxy::RemoteTensor::get_hardware_tensor(const ov::SoPtr<ov::ITensor>& tensor, bool unwrap) {
|
||||
ov::SoPtr<ov::ITensor> hw_tensor = tensor;
|
||||
if (auto remote_tensor = std::dynamic_pointer_cast<ov::proxy::RemoteTensor>(tensor._ptr))
|
||||
return remote_tensor->m_tensor;
|
||||
return tensor;
|
||||
hw_tensor = remote_tensor->m_tensor;
|
||||
|
||||
if (unwrap) {
|
||||
if (auto wrapper = std::dynamic_pointer_cast<ov::RemoteBlobTensor>(hw_tensor._ptr)) {
|
||||
auto blob = ov::get_hardware_blob(wrapper->blob.get());
|
||||
if (auto tensor_holder = dynamic_cast<ov::legacy_convert::TensorHolder*>(blob)) {
|
||||
hw_tensor = tensor_holder->get_tensor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hw_tensor;
|
||||
}
|
||||
|
||||
const ov::SoPtr<ov::ITensor>& ov::proxy::get_hardware_tensor(const ov::SoPtr<ov::ITensor>& tensor) {
|
||||
return ov::proxy::RemoteTensor::get_hardware_tensor(tensor);
|
||||
ov::SoPtr<ov::ITensor> ov::proxy::get_hardware_tensor(const ov::SoPtr<ov::ITensor>& tensor, bool unwrap) {
|
||||
return ov::proxy::RemoteTensor::get_hardware_tensor(tensor, unwrap);
|
||||
}
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
|
||||
const ov::Strides& get_strides() const override;
|
||||
|
||||
static const ov::SoPtr<ov::ITensor>& get_hardware_tensor(const ov::SoPtr<ov::ITensor>& tensor);
|
||||
static ov::SoPtr<ov::ITensor> get_hardware_tensor(const ov::SoPtr<ov::ITensor>& tensor, bool unwrap);
|
||||
|
||||
private:
|
||||
mutable std::string m_name;
|
||||
|
||||
Reference in new issue
Block a user