Skip to content

Commit

Permalink
Added throws
Browse files Browse the repository at this point in the history
Signed-off-by: Alexandru Enache <[email protected]>
  • Loading branch information
alexandruenache1111 authored and MirceaDan99 committed Dec 15, 2024
1 parent 99b823b commit eea8d49
Show file tree
Hide file tree
Showing 3 changed files with 269 additions and 33 deletions.
124 changes: 124 additions & 0 deletions src/plugins/intel_npu/src/plugin/src/metadata.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "metadata.hpp"

#include <cstring>
#include <sstream>

#include "intel_npu/config/config.hpp"
#include "intel_npu/utils/logger/logger.hpp"
#include "openvino/core/version.hpp"

namespace intel_npu {

OpenvinoVersion::OpenvinoVersion(std::string_view version)
: _version(version),
_size(static_cast<uint32_t>(version.size())) {}

void OpenvinoVersion::read(std::istream& stream) {
stream.read(reinterpret_cast<char*>(&_size), sizeof(_size));
_version.resize(_size);
stream.read(_version.data(), _size);
}

Metadata<METADATA_VERSION_1_0>::Metadata()
: _version{METADATA_VERSION_1_0},
_ovVersion{ov::get_openvino_version().buildNumber} {}

void Metadata<METADATA_VERSION_1_0>::read(std::istream& stream) {
_ovVersion.read(stream);
}

uint32_t& OpenvinoVersion::get_size() {
return _size;
}

void Metadata<METADATA_VERSION_1_0>::write(std::ostream& stream) {
stream.write(reinterpret_cast<const char*>(&_version), sizeof(_version));
stream.write(reinterpret_cast<const char*>(&_ovVersion.get_size()), sizeof(_ovVersion.get_size()));
stream.write(_ovVersion.get_version().data(), _ovVersion.get_version().size());
}

std::unique_ptr<MetadataBase> create_metadata(uint32_t version) {
switch (version) {
case METADATA_VERSION_1_0:
return std::make_unique<Metadata<METADATA_VERSION_1_0>>();

default:
OPENVINO_THROW("Invalid metadata version!");
}
}

std::string OpenvinoVersion::get_version() {
return _version;
}

bool Metadata<METADATA_VERSION_1_0>::is_compatible() {
Logger logger("NPUPlugin", Logger::global().level());
// checking if we can import the blob
if (_ovVersion.get_version() != ov::get_openvino_version().buildNumber) {
logger.warning("Imported blob OpenVINO version: %s, but the current OpenVINO version is: %s",
_ovVersion.get_version().c_str(),
ov::get_openvino_version().buildNumber);

#ifdef NPU_PLUGIN_DEVELOPER_BUILD
if (auto envVar = std::getenv("NPU_DISABLE_VERSION_CHECK")) {
if (envVarStrToBool("NPU_DISABLE_VERSION_CHECK", envVar)) {
return true;
}
}
#endif
return false;
}
return true;
}

std::unique_ptr<MetadataBase> read_metadata_from(const std::vector<uint8_t>& blob) {
Logger logger("NPUPlugin", Logger::global().level());
size_t magicBytesSize = MAGIC_BYTES.size();
std::string blobMagicBytes;
blobMagicBytes.resize(magicBytesSize);

auto metadataIterator = blob.end() - magicBytesSize;
std::memcpy(blobMagicBytes.data(), &(*metadataIterator), magicBytesSize);
if (MAGIC_BYTES != blobMagicBytes) {
OPENVINO_THROW("Blob is missing NPU metadata!");
}

uint64_t blobDataSize;
metadataIterator -= sizeof(blobDataSize);
std::memcpy(&blobDataSize, &(*metadataIterator), sizeof(blobDataSize));
metadataIterator = blob.begin() + blobDataSize;

std::stringstream metadataStream;
metadataStream.write(reinterpret_cast<const char*>(&(*metadataIterator)),
blob.end() - metadataIterator - sizeof(blobDataSize));

uint32_t metaVersion;
metadataStream.read(reinterpret_cast<char*>(&metaVersion), sizeof(metaVersion));

std::unique_ptr<MetadataBase> storedMeta;
try {
storedMeta = create_metadata(metaVersion);
storedMeta->read(metadataStream);
} catch(...) {
logger.warning("Imported blob metadata version: %d.%d, but the current version is: %d.%d",
get_major(metaVersion),
get_minor(metaVersion),
get_major(CURRENT_METADATA_VERSION),
get_minor(CURRENT_METADATA_VERSION));
}
return storedMeta;
}

void Metadata<METADATA_VERSION_1_0>::set_version(uint32_t newVersion) {
_version = newVersion;
}

void Metadata<METADATA_VERSION_1_0>::set_ov_version(const OpenvinoVersion& newVersion) {
_ovVersion = newVersion;
}

} // namespace intel_npu
89 changes: 56 additions & 33 deletions src/plugins/intel_npu/src/plugin/src/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,24 @@
#include <fstream>

#include "compiled_model.hpp"
#include "compiler_adapter_factory.hpp"
#include "npuw/compiled_model.hpp"
#include "driver_compiler_adapter.hpp"
#include "intel_npu/common/device_helpers.hpp"
#include "intel_npu/common/icompiler_adapter.hpp"
#include "intel_npu/common/igraph.hpp"
#include "intel_npu/common/itt.hpp"
#include "intel_npu/config/common.hpp"
#include "intel_npu/config/compiler.hpp"
#include "intel_npu/config/npuw.hpp"
#include "intel_npu/config/runtime.hpp"
#include "intel_npu/utils/zero/zero_init.hpp"
#include "npuw/compiled_model.hpp"
#include "metadata.hpp"
#include "openvino/op/constant.hpp"
#include "openvino/op/parameter.hpp"
#include "openvino/runtime/intel_npu/properties.hpp"
#include "openvino/runtime/properties.hpp"
#include "plugin_compiler_adapter.hpp"
#include "remote_context.hpp"
#include "zero_backend.hpp"

using namespace intel_npu;

Expand Down Expand Up @@ -698,9 +700,8 @@ std::shared_ptr<ov::ICompiledModel> Plugin::compile_model(const std::shared_ptr<
}
}

auto originalModel = model->clone();
CompilerAdapterFactory compilerAdapterFactory;
auto compiler = compilerAdapterFactory.getCompiler(_backends->getIEngineBackend(), localConfig);
auto original_model = model->clone();
auto compiler = getCompiler(localConfig);

OV_ITT_TASK_NEXT(PLUGIN_COMPILE_MODEL, "compile");
std::shared_ptr<intel_npu::IGraph> graph;
Expand All @@ -716,7 +717,7 @@ std::shared_ptr<ov::ICompiledModel> Plugin::compile_model(const std::shared_ptr<

std::shared_ptr<ov::ICompiledModel> compiledModel;
try {
compiledModel = std::make_shared<CompiledModel>(originalModel, shared_from_this(), device, graph, localConfig);
compiledModel = std::make_shared<CompiledModel>(original_model, shared_from_this(), device, graph, localConfig);
} catch (const std::exception& ex) {
OPENVINO_THROW(ex.what());
} catch (...) {
Expand Down Expand Up @@ -752,14 +753,7 @@ std::shared_ptr<ov::ICompiledModel> Plugin::import_model(std::istream& stream, c
OV_ITT_SCOPED_TASK(itt::domains::NPUPlugin, "Plugin::import_model");
OV_ITT_TASK_CHAIN(PLUGIN_IMPORT_MODEL, itt::domains::NPUPlugin, "Plugin::import_model", "merge_configs");

auto _properties = properties;
std::shared_ptr<ov::AlignedBuffer> modelBuffer;
if (_properties.count(ov::internal::cached_model_buffer.name())) {
modelBuffer = _properties.at(ov::internal::cached_model_buffer.name()).as<std::shared_ptr<ov::AlignedBuffer>>();
_properties.erase(ov::internal::cached_model_buffer.name());
}

const auto propertiesMap = any_copy(_properties);
const std::map<std::string, std::string> propertiesMap = any_copy(properties);
auto localConfig = merge_configs(_globalConfig, propertiesMap, OptionMode::RunTime);
_logger.setLevel(localConfig.get<LOG_LEVEL>());
const auto platform = _backends->getCompilationPlatform(localConfig.get<PLATFORM>(), localConfig.get<DEVICE_ID>());
Expand All @@ -779,27 +773,23 @@ std::shared_ptr<ov::ICompiledModel> Plugin::import_model(std::istream& stream, c
std::shared_ptr<ov::ICompiledModel> compiledModel;

try {
CompilerAdapterFactory compilerAdapterFactory;
auto compiler = compilerAdapterFactory.getCompiler(_backends->getIEngineBackend(), localConfig);

std::unique_ptr<BlobContainer> blobPtr;
auto compiler = getCompiler(localConfig);

if (modelBuffer == nullptr) {
auto graphSize = getFileSize(stream);
auto graphSize = getFileSize(stream);

std::vector<uint8_t> blob(graphSize);
stream.read(reinterpret_cast<char*>(blob.data()), graphSize);
if (!stream) {
OPENVINO_THROW("Failed to read data from stream!");
}
_logger.debug("Successfully read %zu bytes into blob.", graphSize);
std::vector<uint8_t> blob(graphSize);
stream.read(reinterpret_cast<char*>(blob.data()), graphSize);
if (!stream) {
OPENVINO_THROW("Failed to read data from stream!");
}
_logger.debug("Successfully read %zu bytes into blob.", graphSize);

blobPtr = std::make_unique<BlobContainerVector>(std::move(blob));
} else {
blobPtr = std::make_unique<BlobContainerAlignedBuffer>(modelBuffer, stream.tellg(), 0);
auto storedMeta = read_metadata_from(blob);
if (!storedMeta->is_compatible()) {
OPENVINO_THROW("Incompatible blob version!");
}

auto graph = compiler->parse(std::move(blobPtr), localConfig);
auto graph = compiler->parse(std::move(blob), localConfig);
graph->update_network_name("net" + std::to_string(_compiledModelLoadCounter++));

const std::shared_ptr<ov::Model> modelDummy =
Expand Down Expand Up @@ -837,8 +827,7 @@ ov::SupportedOpsMap Plugin::query_model(const std::shared_ptr<const ov::Model>&
const auto platform = _backends->getCompilationPlatform(localConfig.get<PLATFORM>(), localConfig.get<DEVICE_ID>());
localConfig.update({{ov::intel_npu::platform.name(), platform}});

CompilerAdapterFactory compilerAdapterFactory;
auto compiler = compilerAdapterFactory.getCompiler(_backends->getIEngineBackend(), localConfig);
auto compiler = getCompiler(localConfig);
ov::SupportedOpsMap supportedOpsMap;
try {
supportedOpsMap = compiler->query(model, localConfig);
Expand All @@ -851,6 +840,40 @@ ov::SupportedOpsMap Plugin::query_model(const std::shared_ptr<const ov::Model>&
return supportedOpsMap;
}

std::unique_ptr<ICompilerAdapter> Plugin::getCompiler(const Config& config) const {
auto compilerType = config.get<COMPILER_TYPE>();
_logger.debug("performing createCompiler");

switch (compilerType) {
case ov::intel_npu::CompilerType::MLIR: {
if (_backends->getBackendName() != "LEVEL0") {
return std::make_unique<PluginCompilerAdapter>(nullptr);
}

auto zeroBackend = std::dynamic_pointer_cast<ZeroEngineBackend>(_backends->getIEngineBackend()._ptr);
if (zeroBackend == nullptr) {
return std::make_unique<PluginCompilerAdapter>(nullptr);
}

return std::make_unique<PluginCompilerAdapter>(zeroBackend->getInitStruct());
}
case ov::intel_npu::CompilerType::DRIVER: {
if (_backends->getBackendName() != "LEVEL0") {
OPENVINO_THROW("NPU Compiler Adapter must be used with LEVEL0 backend");
}

auto zeroBackend = std::dynamic_pointer_cast<ZeroEngineBackend>(_backends->getIEngineBackend()._ptr);
if (!zeroBackend) {
OPENVINO_THROW("Failed to cast zeroBackend, zeroBackend is a nullptr");
}

return std::make_unique<DriverCompilerAdapter>(zeroBackend->getInitStruct());
}
default:
OPENVINO_THROW("Invalid NPU_COMPILER_TYPE");
}
}

std::atomic<int> Plugin::_compiledModelLoadCounter{1};

static const ov::Version version = {CI_BUILD_NUMBER, NPU_PLUGIN_LIB_NAME};
Expand Down
89 changes: 89 additions & 0 deletions src/plugins/intel_npu/tests/unit/npu/metadata_version.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright (C) 2018-2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include <gtest/gtest.h>

#include "common_test_utils/test_assertions.hpp"
#include "metadata.hpp"

using namespace intel_npu;

using MetadataUnitTests = ::testing::Test;

struct MetadataTest : Metadata<CURRENT_METADATA_VERSION> {
void set_version(uint32_t newVersion) {
_version = newVersion;
}

void set_ov_version(const OpenvinoVersion& newVersion) {
_ovVersion = newVersion;
}
};

TEST_F(MetadataUnitTests, readUnversionedBlob) {
std::vector<uint8_t> blob(50, 68);

std::unique_ptr<MetadataBase> storedMeta;
ASSERT_ANY_THROW(storedMeta = read_metadata_from(blob));
ASSERT_EQ(storedMeta, nullptr);
}

TEST_F(MetadataUnitTests, writeAndReadMetadataFromBlob) {
std::stringstream stream;
size_t blobSize = 0;
auto meta = MetadataTest();

OV_ASSERT_NO_THROW(meta.write(stream));
OV_ASSERT_NO_THROW(stream.write(reinterpret_cast<const char*>(&blobSize), sizeof(blobSize)));
OV_ASSERT_NO_THROW(stream.write(MAGIC_BYTES.data(), MAGIC_BYTES.size()));

blobSize = stream.str().length();

std::vector<uint8_t> blob(blobSize);
OV_ASSERT_NO_THROW(stream.read(reinterpret_cast<char*>(blob.data()), blobSize));
auto storedMeta = read_metadata_from(blob);
ASSERT_NE(storedMeta, nullptr);
ASSERT_TRUE(storedMeta->is_compatible());
}

TEST_F(MetadataUnitTests, writeAndReadInvalidOpenvinoVersion) {
size_t blobSize = 0;
std::stringstream stream;
auto meta = MetadataTest();

OpenvinoVersion badOvVersion("just_some_wrong_ov_version");
meta.set_ov_version(badOvVersion);

OV_ASSERT_NO_THROW(meta.write(stream));
OV_ASSERT_NO_THROW(stream.write(reinterpret_cast<const char*>(&blobSize), sizeof(blobSize)));
OV_ASSERT_NO_THROW(stream.write(MAGIC_BYTES.data(), MAGIC_BYTES.size()));

blobSize = stream.str().length();

std::vector<uint8_t> blob(blobSize);
OV_ASSERT_NO_THROW(stream.read(reinterpret_cast<char*>(blob.data()), blobSize));
auto storedMeta = read_metadata_from(blob);
ASSERT_NE(storedMeta, nullptr);
ASSERT_FALSE(storedMeta->is_compatible());
}

TEST_F(MetadataUnitTests, writeAndReadInvalidMetadataVersion) {
size_t blobSize = 0;
std::stringstream stream;
auto meta = Metadata<CURRENT_METADATA_VERSION>();

constexpr uint32_t dummy_version = make_version(0x00007E57, 0x0000AC3D);
meta.set_version(dummy_version);

OV_ASSERT_NO_THROW(meta.write(stream));
OV_ASSERT_NO_THROW(stream.write(reinterpret_cast<const char*>(&blobSize), sizeof(blobSize)));
OV_ASSERT_NO_THROW(stream.write(MAGIC_BYTES.data(), MAGIC_BYTES.size()));

blobSize = stream.str().length();

std::vector<uint8_t> blob(blobSize);
OV_ASSERT_NO_THROW(stream.read(reinterpret_cast<char*>(blob.data()), blobSize));
auto storedMeta = read_metadata_from(blob);
ASSERT_EQ(storedMeta, nullptr);
}

0 comments on commit eea8d49

Please sign in to comment.