diff --git a/src/inference/dev_api/openvino/runtime/compilation_context.hpp b/src/inference/dev_api/openvino/runtime/compilation_context.hpp index 14799620db58fd..4388b7279d2c53 100644 --- a/src/inference/dev_api/openvino/runtime/compilation_context.hpp +++ b/src/inference/dev_api/openvino/runtime/compilation_context.hpp @@ -35,6 +35,7 @@ class CompiledBlobHeader final { std::string m_ieVersion; std::string m_fileInfo; std::string m_runtimeInfo; + std::string m_blobVersion; uint32_t m_headerSizeAlignment{0}; public: @@ -42,6 +43,7 @@ class CompiledBlobHeader final { CompiledBlobHeader(const std::string& ieVersion, const std::string& fileInfo, const std::string& runtimeInfo, + const std::string& blobVersion, const uint32_t headerSizeAlignment = 0); const std::string& get_openvino_version() const { @@ -56,6 +58,10 @@ class CompiledBlobHeader final { return m_runtimeInfo; } + const std::string& get_blob_version() const { + return m_blobVersion; + } + const uint32_t get_header_size_alignment() const { return m_headerSizeAlignment; } diff --git a/src/inference/dev_api/openvino/runtime/internal_properties.hpp b/src/inference/dev_api/openvino/runtime/internal_properties.hpp index 7100aeb9a8728c..5872426955edd0 100644 --- a/src/inference/dev_api/openvino/runtime/internal_properties.hpp +++ b/src/inference/dev_api/openvino/runtime/internal_properties.hpp @@ -169,5 +169,18 @@ static constexpr Property key_cache_quan */ static constexpr Property value_cache_quant_mode{"VALUE_CACHE_QUANT_MODE"}; + +/** + * @brief Read-only property to get a compiled blob version. + * @ingroup ov_dev_api_plugin_api + */ +static constexpr Property compiled_blob_version{"COMPILED_BLOB_VERSION"}; + +/** + * @brief Read-only property to get a callback to verify compiled blob version compatibility. + * @ingroup ov_dev_api_plugin_api + */ +using blob_verification_callback_t = std::function; +static constexpr Property blob_verification_callback{"BLOB_VERIFICATION_CALLBACK"}; } // namespace internal } // namespace ov diff --git a/src/inference/src/dev/compilation_context.cpp b/src/inference/src/dev/compilation_context.cpp index fbb3579e337b2f..d2ac1f1730619c 100644 --- a/src/inference/src/dev/compilation_context.cpp +++ b/src/inference/src/dev/compilation_context.cpp @@ -176,10 +176,12 @@ CompiledBlobHeader::CompiledBlobHeader() {} CompiledBlobHeader::CompiledBlobHeader(const std::string& ieVersion, const std::string& fileInfo, const std::string& runtimeInfo, + const std::string& blobVersion, const uint32_t headerSizeAlignment) : m_ieVersion(ieVersion), m_fileInfo(fileInfo), m_runtimeInfo(runtimeInfo), + m_blobVersion(blobVersion), m_headerSizeAlignment(headerSizeAlignment) {} std::istream& operator>>(std::istream& stream, CompiledBlobHeader& header) { @@ -197,6 +199,7 @@ std::istream& operator>>(std::istream& stream, CompiledBlobHeader& header) { header.m_ieVersion = ov::util::pugixml::get_str_attr(compiledBlobNode, "ie_version"); header.m_fileInfo = ov::util::pugixml::get_str_attr(compiledBlobNode, "file_info"); header.m_runtimeInfo = ov::util::pugixml::get_str_attr(compiledBlobNode, "runtime_info"); + header.m_blobVersion = ov::util::pugixml::get_str_attr(compiledBlobNode, "blob_version"); header.m_headerSizeAlignment = ov::util::pugixml::get_uint_attr(compiledBlobNode, "header_size_alignment"); if (const auto pad = util::align_padding_size(header.m_headerSizeAlignment, bytes_read); pad > 0) { @@ -213,6 +216,7 @@ std::ostream& operator<<(std::ostream& stream, const CompiledBlobHeader& header) compiledBlobNode.append_attribute("ie_version").set_value(header.m_ieVersion.c_str()); compiledBlobNode.append_attribute("file_info").set_value(header.m_fileInfo.c_str()); compiledBlobNode.append_attribute("runtime_info").set_value(header.m_runtimeInfo.c_str()); + compiledBlobNode.append_attribute("blob_version").set_value(header.m_blobVersion.c_str()); compiledBlobNode.append_attribute("header_size_alignment") .set_value(std::to_string(header.m_headerSizeAlignment).c_str()); @@ -261,6 +265,7 @@ void CompiledBlobHeader::read_from_buffer(const char* buffer, size_t buffer_size m_ieVersion = ov::util::pugixml::get_str_attr(compiledBlobNode, "ie_version"); m_fileInfo = ov::util::pugixml::get_str_attr(compiledBlobNode, "file_info"); m_runtimeInfo = ov::util::pugixml::get_str_attr(compiledBlobNode, "runtime_info"); + m_blobVersion = ov::util::pugixml::get_str_attr(compiledBlobNode, "blob_version"); m_headerSizeAlignment = ov::util::pugixml::get_uint_attr(compiledBlobNode, "header_size_alignment"); pos += util::align_padding_size(m_headerSizeAlignment, pos - start); diff --git a/src/inference/src/dev/core_impl.cpp b/src/inference/src/dev/core_impl.cpp index 6637d83961868b..7eb5f921a7cacf 100644 --- a/src/inference/src/dev/core_impl.cpp +++ b/src/inference/src/dev/core_impl.cpp @@ -1551,9 +1551,16 @@ ov::SoPtr ov::CoreImpl::compile_model_and_cache(ov::Plugin& plugin.get_property(ov::internal::cache_header_alignment.name(), {}).as(); } + std::string compiled_blob_version; + if (device_supports_internal_property(plugin, ov::internal::compiled_blob_version.name())) { + compiled_blob_version = + plugin.get_property(ov::internal::compiled_blob_version.name(), {}).as(); + } + networkStream << ov::CompiledBlobHeader(ov::get_openvino_version().buildNumber, ov::ModelCache::calculate_file_info(cacheContent.m_model_path), compiled_model_runtime_properties, + compiled_blob_version, header_size_alignment); compiled_model->export_model(networkStream); @@ -1621,6 +1628,7 @@ ov::SoPtr ov::CoreImpl::load_model_from_cache( OPENVINO_THROW("Version does not match"); } } + OPENVINO_ASSERT(plugin.verify_compiled_blob(header.get_blob_version()), "Incompatible blob version"); } catch (...) { throw HeaderException(); } diff --git a/src/inference/src/dev/plugin.cpp b/src/inference/src/dev/plugin.cpp index 9d771870979bac..aca852949556d3 100644 --- a/src/inference/src/dev/plugin.cpp +++ b/src/inference/src/dev/plugin.cpp @@ -119,3 +119,10 @@ bool ov::Plugin::supports_model_caching(const ov::AnyMap& arguments) const { util::contains(get_property(ov::internal::supported_properties), ov::internal::caching_properties); return supported; } + +bool ov::Plugin::verify_compiled_blob(const std::string& compiled_blob_version) const { + if (util::contains(get_property(ov::internal::supported_properties), ov::internal::blob_verification_callback)) { + return get_property(ov::internal::blob_verification_callback)(compiled_blob_version); + } + return true; +} diff --git a/src/inference/src/dev/plugin.hpp b/src/inference/src/dev/plugin.hpp index f62ac514f90859..c57ccd7a58ee6d 100644 --- a/src/inference/src/dev/plugin.hpp +++ b/src/inference/src/dev/plugin.hpp @@ -81,6 +81,8 @@ class Plugin { return get_property(property.name(), arguments).template as(); } bool supports_model_caching(const AnyMap& arguments = {}) const; + + bool verify_compiled_blob(const std::string& compiled_blob_version) const; }; } // namespace ov diff --git a/src/plugins/template/src/plugin.cpp b/src/plugins/template/src/plugin.cpp index 3a3d3ce20e32a7..765a629dbf9270 100644 --- a/src/plugins/template/src/plugin.cpp +++ b/src/plugins/template/src/plugin.cpp @@ -394,6 +394,8 @@ ov::Any ov::template_plugin::Plugin::get_property(const std::string& name, const ov::PropertyName{ov::internal::threads_per_stream.name(), ov::PropertyMutability::RW}, ov::PropertyName{ov::internal::compiled_model_runtime_properties.name(), ov::PropertyMutability::RO}, ov::PropertyName{ov::internal::cache_header_alignment.name(), ov::PropertyMutability::RO}, + ov::PropertyName{ov::internal::compiled_blob_version.name(), ov::PropertyMutability::RO}, + ov::PropertyName{ov::internal::blob_verification_callback.name(), ov::PropertyMutability::RO}, }; } else if (ov::available_devices == name) { // TODO: fill list of available devices @@ -415,12 +417,26 @@ ov::Any ov::template_plugin::Plugin::get_property(const std::string& name, const return decltype(ov::execution_devices)::value_type{get_device_name()}; } else if (ov::range_for_async_infer_requests == name) { return decltype(ov::range_for_async_infer_requests)::value_type{1, 1, 1}; + } else if (ov::internal::blob_verification_callback == name) { + return decltype(ov::internal::blob_verification_callback)::value_type{[](const std::string& version) { + return ov::template_plugin::Plugin::verify_compiled_blob(version); + }}; + } else if (ov::internal::compiled_blob_version == name) { + return decltype(ov::internal::compiled_blob_version)::value_type{get_compiled_blob_version()}; } else { return m_cfg.Get(name); } } // ! [plugin:get_property] +std::string ov::template_plugin::Plugin::get_compiled_blob_version() { + return "TEMPLATE_PLUGIN_BLOB_V1"; +} + +bool ov::template_plugin::Plugin::verify_compiled_blob(const std::string& compiled_blob_version) { + return compiled_blob_version == get_compiled_blob_version(); +} + // ! [plugin:create_plugin_engine] static const ov::Version version = {CI_BUILD_NUMBER, "openvino_template_plugin"}; OV_DEFINE_PLUGIN_CREATE_FUNCTION(ov::template_plugin::Plugin, version) diff --git a/src/plugins/template/src/plugin.hpp b/src/plugins/template/src/plugin.hpp index 9ec2b1c5decac3..12cf46f9dda802 100644 --- a/src/plugins/template/src/plugin.hpp +++ b/src/plugins/template/src/plugin.hpp @@ -58,8 +58,10 @@ class Plugin : public ov::IPlugin { std::shared_ptr m_backend; Configuration m_cfg; std::shared_ptr m_waitExecutor; -}; + static std::string get_compiled_blob_version(); + static bool verify_compiled_blob(const std::string& compiled_blob_version); +}; } // namespace template_plugin } // namespace ov //! [plugin:header]