Skip to content

Commit a2522be

Browse files
committed
Cherry-pick from alexandruenache1111:blob_stream_commit
1 parent 99b823b commit a2522be

File tree

11 files changed

+392
-9
lines changed

11 files changed

+392
-9
lines changed

src/plugins/intel_npu/src/common/include/intel_npu/common/igraph.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class IGraph : public std::enable_shared_from_this<IGraph> {
2424
const Config& config,
2525
std::unique_ptr<BlobContainer> blobPtr);
2626

27-
virtual void export_blob(std::ostream& stream) const = 0;
27+
virtual size_t export_blob(std::ostream& stream) const = 0;
2828

2929
virtual std::vector<ov::ProfilingInfo> process_profiling_output(const std::vector<uint8_t>& profData,
3030
const Config& config) const = 0;

src/plugins/intel_npu/src/compiler_adapter/include/driver_graph.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class DriverGraph final : public IGraph {
2323
const Config& config,
2424
std::unique_ptr<BlobContainer> blob);
2525

26-
void export_blob(std::ostream& stream) const override;
26+
size_t export_blob(std::ostream& stream) const override;
2727

2828
std::vector<ov::ProfilingInfo> process_profiling_output(const std::vector<uint8_t>& profData,
2929
const Config& config) const override;

src/plugins/intel_npu/src/compiler_adapter/include/plugin_graph.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class PluginGraph final : public IGraph {
2626
std::unique_ptr<BlobContainer> blobPtr,
2727
const Config& config);
2828

29-
void export_blob(std::ostream& stream) const override;
29+
size_t export_blob(std::ostream& stream) const override;
3030

3131
std::vector<ov::ProfilingInfo> process_profiling_output(const std::vector<uint8_t>& profData,
3232
const Config& config) const override;

src/plugins/intel_npu/src/compiler_adapter/src/driver_graph.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ DriverGraph::DriverGraph(const std::shared_ptr<ZeGraphExtWrappers>& zeGraphExt,
3232
initialize(config);
3333
}
3434

35-
void DriverGraph::export_blob(std::ostream& stream) const {
35+
size_t DriverGraph::export_blob(std::ostream& stream) const {
3636
const uint8_t* blobPtr = nullptr;
37-
size_t blobSize = -1;
37+
size_t blobSize;
3838
std::vector<uint8_t> blob;
3939

4040
if (_blobIsReleased) {
@@ -47,7 +47,7 @@ void DriverGraph::export_blob(std::ostream& stream) const {
4747

4848
if (!stream) {
4949
_logger.error("Write blob to stream failed. Blob is broken!");
50-
return;
50+
return 0;
5151
}
5252

5353
if (_logger.level() >= ov::log::Level::INFO) {
@@ -61,6 +61,7 @@ void DriverGraph::export_blob(std::ostream& stream) const {
6161
_logger.info(str.str().c_str());
6262
}
6363
_logger.info("Write blob to stream successfully.");
64+
return blobSize;
6465
}
6566

6667
std::vector<ov::ProfilingInfo> DriverGraph::process_profiling_output(const std::vector<uint8_t>& profData,

src/plugins/intel_npu/src/compiler_adapter/src/plugin_graph.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ PluginGraph::PluginGraph(const std::shared_ptr<ZeGraphExtWrappers>& zeGraphExt,
3030
initialize(config);
3131
}
3232

33-
void PluginGraph::export_blob(std::ostream& stream) const {
33+
size_t PluginGraph::export_blob(std::ostream& stream) const {
3434
stream.write(reinterpret_cast<const char*>(_blobPtr->get_ptr()), _blobPtr->size());
3535

3636
if (!stream) {
3737
_logger.error("Write blob to stream failed. Blob is broken!");
38-
return;
38+
return 0;
3939
}
4040

4141
if (_logger.level() >= ov::log::Level::INFO) {
@@ -51,6 +51,7 @@ void PluginGraph::export_blob(std::ostream& stream) const {
5151
_logger.info(str.str().c_str());
5252
}
5353
_logger.info("Write blob to stream successfully.");
54+
return _blob.size();
5455
}
5556

5657
std::vector<ov::ProfilingInfo> PluginGraph::process_profiling_output(const std::vector<uint8_t>& profData,
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
// Copyright (C) 2018-2024 Intel Corporation
2+
// SPDX-License-Identifier: Apache-2.0
3+
//
4+
5+
#pragma once
6+
7+
#include <stdint.h>
8+
9+
#include <memory>
10+
#include <optional>
11+
#include <string>
12+
#include <vector>
13+
14+
namespace intel_npu {
15+
16+
/**
17+
* @brief Magic bytes used for identifying NPU blobs.
18+
*/
19+
constexpr std::string_view MAGIC_BYTES = "OVNPU";
20+
21+
namespace {
22+
/**
23+
* @brief Returns a uint32_t value which represents two uint16_t values concatenated.
24+
* @details Convention for bumping the metadata version:
25+
* - Increment Major in case of: removing a current field OR adding a new field in between fields.
26+
* - Increment Minor in case of: adding a new field at the end.
27+
*
28+
* @return Major and minor versions concatenated into a single uint32_t value.
29+
*/
30+
constexpr uint32_t make_version(uint16_t major, uint16_t minor) {
31+
return major << 16 | (minor & 0x0000ffff);
32+
}
33+
34+
/**
35+
* @brief Gets the major version.
36+
*
37+
* @return Major version.
38+
*/
39+
constexpr uint16_t get_major(uint32_t version) {
40+
return static_cast<uint16_t>(version >> 16);
41+
}
42+
43+
/**
44+
* @brief Gets the minor version.
45+
*
46+
* @return Minor version.
47+
*/
48+
constexpr uint16_t get_minor(uint32_t version) {
49+
return static_cast<uint16_t>(version);
50+
}
51+
} // anonymous namespace
52+
53+
/**
54+
* @brief List of supported version formats.
55+
*/
56+
constexpr uint32_t METADATA_VERSION_1_0{make_version(1, 0)};
57+
58+
/**
59+
* @brief Current metadata version.
60+
*/
61+
constexpr uint32_t CURRENT_METADATA_VERSION{METADATA_VERSION_1_0};
62+
63+
struct OpenvinoVersion {
64+
private:
65+
std::string _version;
66+
uint32_t _size;
67+
68+
public:
69+
OpenvinoVersion();
70+
71+
OpenvinoVersion(std::string_view version);
72+
73+
/**
74+
* @brief Reads version data from a stream.
75+
*/
76+
void read(std::istream& stream);
77+
78+
/**
79+
* @brief Writes version data to a stream.
80+
*/
81+
void write(std::ostream& stream);
82+
83+
/**
84+
* @brief Gets the version string.
85+
*/
86+
std::string get_version();
87+
};
88+
89+
struct MetadataBase {
90+
/**
91+
* @brief Reads metadata from a stream.
92+
*/
93+
virtual void read(std::istream& stream) = 0;
94+
95+
/**
96+
* @brief Writes metadata to a stream.
97+
*/
98+
virtual void write(std::ostream& stream) = 0;
99+
100+
virtual bool is_compatible() = 0;
101+
102+
virtual ~MetadataBase() = default;
103+
};
104+
105+
/**
106+
* @brief Template for metadata class handling.
107+
*
108+
* @attention It's a must to have metadata version as first field in any metadata specialization.
109+
*/
110+
template <uint32_t version>
111+
struct Metadata : public MetadataBase {};
112+
113+
/**
114+
* @brief Template specialization for metadata version 1.0.
115+
*/
116+
template <>
117+
struct Metadata<METADATA_VERSION_1_0> : public MetadataBase {
118+
protected:
119+
uint32_t _version;
120+
OpenvinoVersion _ovVersion;
121+
122+
public:
123+
Metadata(std::optional<std::string_view> ovVersion = std::nullopt);
124+
125+
void read(std::istream& stream) override;
126+
127+
void write(std::ostream& stream) override;
128+
129+
/**
130+
* @brief Checks if metadata is supported.
131+
*
132+
* @return Returns:
133+
* - false:
134+
* - if blob metadata does not match current metadata.
135+
* - if blob OpenVINO version does not match current one.
136+
*
137+
* - true: if all versions match.
138+
*
139+
* @note The version check can be disabled if the "NPU_DISABLE_VERSION_CHECK" environment variable is set to '1'.
140+
*/
141+
bool is_compatible() override;
142+
};
143+
144+
/**
145+
* @brief Creates a Metadata object.
146+
*
147+
* @return Unique pointer to the created MetadataBase object if the major version is supported; otherwise, returns
148+
* 'nullptr'.
149+
*/
150+
std::unique_ptr<MetadataBase> create_metadata(uint32_t version);
151+
152+
/**
153+
* @brief Reads metadata from a blob.
154+
*
155+
* @return If the blob is versioned and its major version is supported, returns an unique pointer to the read
156+
* MetadataBase object; otherwise, returns 'nullptr'.
157+
*/
158+
std::unique_ptr<MetadataBase> read_metadata_from(const std::vector<uint8_t>& blob);
159+
160+
} // namespace intel_npu

src/plugins/intel_npu/src/plugin/src/compiled_model.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "intel_npu/config/compiler.hpp"
1414
#include "intel_npu/config/config.hpp"
1515
#include "intel_npu/config/runtime.hpp"
16+
#include "metadata.hpp"
1617
#include "openvino/pass/constant_folding.hpp"
1718
#include "openvino/pass/manager.hpp"
1819
#include "openvino/runtime/properties.hpp"
@@ -72,7 +73,12 @@ std::shared_ptr<ov::ISyncInferRequest> CompiledModel::create_sync_infer_request(
7273

7374
void CompiledModel::export_model(std::ostream& stream) const {
7475
_logger.debug("CompiledModel::export_model");
75-
_graph->export_blob(stream);
76+
size_t blobSizeBeforeVersioning = _graph->export_blob(stream);
77+
78+
auto meta = Metadata<CURRENT_METADATA_VERSION>(ov::get_openvino_version().buildNumber);
79+
meta.write(stream);
80+
stream.write(reinterpret_cast<const char*>(&blobSizeBeforeVersioning), sizeof(blobSizeBeforeVersioning));
81+
stream.write(MAGIC_BYTES.data(), MAGIC_BYTES.size());
7682
}
7783

7884
std::shared_ptr<const ov::Model> CompiledModel::get_runtime_model() const {
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// Copyright (C) 2018-2024 Intel Corporation
2+
// SPDX-License-Identifier: Apache-2.0
3+
//
4+
5+
#include "metadata.hpp"
6+
7+
#include <cstring>
8+
#include <optional>
9+
#include <sstream>
10+
11+
#include "intel_npu/config/config.hpp"
12+
#include "intel_npu/utils/logger/logger.hpp"
13+
#include "openvino/core/version.hpp"
14+
15+
namespace intel_npu {
16+
17+
OpenvinoVersion::OpenvinoVersion(std::string_view version)
18+
: _version(version),
19+
_size(static_cast<uint32_t>(version.size())) {}
20+
21+
void OpenvinoVersion::read(std::istream& stream) {
22+
stream.read(reinterpret_cast<char*>(&_size), sizeof(_size));
23+
_version.resize(_size);
24+
stream.read(_version.data(), _size);
25+
}
26+
27+
void OpenvinoVersion::write(std::ostream& stream) {
28+
stream.write(reinterpret_cast<const char*>(&_size), sizeof(_size));
29+
stream.write(_version.data(), _size);
30+
}
31+
32+
Metadata<METADATA_VERSION_1_0>::Metadata(std::optional<std::string_view> ovVersion)
33+
: _version{METADATA_VERSION_1_0},
34+
_ovVersion{ovVersion.value_or(ov::get_openvino_version().buildNumber)} {}
35+
36+
void Metadata<METADATA_VERSION_1_0>::read(std::istream& stream) {
37+
_ovVersion.read(stream);
38+
}
39+
40+
void Metadata<METADATA_VERSION_1_0>::write(std::ostream& stream) {
41+
stream.write(reinterpret_cast<const char*>(&_version), sizeof(_version));
42+
_ovVersion.write(stream);
43+
}
44+
45+
std::unique_ptr<MetadataBase> create_metadata(uint32_t version) {
46+
switch (version) {
47+
case METADATA_VERSION_1_0:
48+
return std::make_unique<Metadata<METADATA_VERSION_1_0>>(std::nullopt);
49+
50+
default:
51+
OPENVINO_THROW("Invalid metadata version!");
52+
}
53+
}
54+
55+
std::string OpenvinoVersion::get_version() {
56+
return _version;
57+
}
58+
59+
bool Metadata<METADATA_VERSION_1_0>::is_compatible() {
60+
Logger logger("NPUPlugin", Logger::global().level());
61+
// checking if we can import the blob
62+
if (_ovVersion.get_version() != ov::get_openvino_version().buildNumber) {
63+
logger.warning("Imported blob OpenVINO version: %s, but the current OpenVINO version is: %s",
64+
_ovVersion.get_version().c_str(),
65+
ov::get_openvino_version().buildNumber);
66+
67+
#ifdef NPU_PLUGIN_DEVELOPER_BUILD
68+
if (auto envVar = std::getenv("NPU_DISABLE_VERSION_CHECK")) {
69+
if (envVarStrToBool("NPU_DISABLE_VERSION_CHECK", envVar)) {
70+
return true;
71+
}
72+
}
73+
#endif
74+
return false;
75+
}
76+
return true;
77+
}
78+
79+
std::unique_ptr<MetadataBase> read_metadata_from(const std::vector<uint8_t>& blob) {
80+
Logger logger("NPUPlugin", Logger::global().level());
81+
size_t magicBytesSize = MAGIC_BYTES.size();
82+
std::string blobMagicBytes;
83+
blobMagicBytes.resize(magicBytesSize);
84+
85+
auto metadataIterator = blob.end() - magicBytesSize;
86+
std::memcpy(blobMagicBytes.data(), &(*metadataIterator), magicBytesSize);
87+
if (MAGIC_BYTES != blobMagicBytes) {
88+
OPENVINO_THROW("Blob is missing NPU metadata!");
89+
}
90+
91+
uint64_t blobDataSize;
92+
metadataIterator -= sizeof(blobDataSize);
93+
std::memcpy(&blobDataSize, &(*metadataIterator), sizeof(blobDataSize));
94+
metadataIterator = blob.begin() + blobDataSize;
95+
96+
std::stringstream metadataStream;
97+
metadataStream.write(reinterpret_cast<const char*>(&(*metadataIterator)),
98+
blob.end() - metadataIterator - sizeof(blobDataSize));
99+
100+
uint32_t metaVersion;
101+
metadataStream.read(reinterpret_cast<char*>(&metaVersion), sizeof(metaVersion));
102+
103+
std::unique_ptr<MetadataBase> storedMeta;
104+
try {
105+
storedMeta = create_metadata(metaVersion);
106+
storedMeta->read(metadataStream);
107+
} catch (...) {
108+
logger.warning("Imported blob metadata version: %d.%d, but the current version is: %d.%d",
109+
get_major(metaVersion),
110+
get_minor(metaVersion),
111+
get_major(CURRENT_METADATA_VERSION),
112+
get_minor(CURRENT_METADATA_VERSION));
113+
114+
OPENVINO_THROW("NPU metadata mismatch.");
115+
}
116+
return storedMeta;
117+
}
118+
119+
} // namespace intel_npu

0 commit comments

Comments
 (0)