[GNA] Add OV & GNA versions to GNA export file (#13141)
* [GNA] Add OV & GNA versions to GNA export file (#86924) * [GNA] Add UT for OV & GNA ver. export/import from model
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
#include "gna_plugin.hpp"
|
||||
#include "gna_model_serial.hpp"
|
||||
#include "serial/headers/latest/gna_model_header.hpp"
|
||||
#include "common/versioning.hpp"
|
||||
|
||||
using namespace GNAPluginNS;
|
||||
|
||||
@@ -91,6 +92,20 @@ inline bool is_little_endian() {
|
||||
return LECheck.c[0] == 1;
|
||||
}
|
||||
|
||||
void GNAVersionSerializer::Export(std::ostream& os) const {
|
||||
writeString(ov::intel_gna::common::get_openvino_version_string(), os);
|
||||
writeString(GNADeviceHelper::GetGnaLibraryVersion(), os);
|
||||
}
|
||||
|
||||
std::string GNAVersionSerializer::Import(std::istream& is) const {
|
||||
std::string version;
|
||||
if (is.peek() && !is.eof()) {
|
||||
version = "The model was exported with OpenVINO version:\n" + readString(is) + "\n";
|
||||
version += "GNA Library version:\n" + readString(is) + "\n";
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
const int gna_header_magic = is_little_endian() ? 0x4d414e47 : 0x474e414d;
|
||||
|
||||
GNAPluginNS::HeaderLatest::ModelHeader GNAModelSerial::ReadHeader(std::istream &is) {
|
||||
@@ -247,7 +262,8 @@ void GNAModelSerial::Import(void *basePointer,
|
||||
GNAPluginNS::GnaInputs &inputs,
|
||||
GNAPluginNS::GnaOutputs &outputs,
|
||||
TranspositionInfoMap &inputsTranspositionInfo,
|
||||
TranspositionInfoMap &outputsTranspositionInfo) {
|
||||
TranspositionInfoMap &outputsTranspositionInfo,
|
||||
std::string & libVersionFromFile) {
|
||||
is.exceptions(std::istream::failbit);
|
||||
// 2. Read inputs names
|
||||
if (model_header_.version.major == 2) {
|
||||
@@ -374,6 +390,11 @@ void GNAModelSerial::Import(void *basePointer,
|
||||
|
||||
// once structure has been read lets read whole gna graph
|
||||
is.read(reinterpret_cast<char*>(basePointer), gnaGraphSize);
|
||||
|
||||
// read OV and GNA versions if available in model file
|
||||
if (model_header_.version.major == 2 && model_header_.version.minor >= 8) {
|
||||
libVersionFromFile = version_.Import(is);
|
||||
}
|
||||
}
|
||||
|
||||
void GNAModelSerial::Export(const GnaAllocations& allocations, std::ostream& os) const {
|
||||
@@ -535,6 +556,9 @@ void GNAModelSerial::Export(const GnaAllocations& allocations, std::ostream& os)
|
||||
for (const auto& a : allocationsOrdered) {
|
||||
os.write(reinterpret_cast<char*>(a.ptr), a.sizeForExport());
|
||||
}
|
||||
|
||||
// write OV & GNA versions
|
||||
version_.Export(os);
|
||||
}
|
||||
|
||||
void GNAModelSerial::ImportInputs(std::istream &is, void* basePtr, GNAPluginNS::GnaInputs &inputs) {
|
||||
|
||||
@@ -16,6 +16,15 @@
|
||||
|
||||
#include "gna_device_allocation.hpp"
|
||||
|
||||
/**
|
||||
* @brief helper class for GNAGraph serialization tasks
|
||||
*/
|
||||
class GNAVersionSerializer {
|
||||
public:
|
||||
void Export(std::ostream& os) const;
|
||||
std::string Import(std::istream& is) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief implements serialization tasks for GNAGraph
|
||||
*/
|
||||
@@ -31,6 +40,7 @@ private:
|
||||
TranspositionInfoMap inputs_transpose_info_;
|
||||
TranspositionInfoMap outputs_transpose_info_;
|
||||
GNAPluginNS::HeaderLatest::ModelHeader model_header_;
|
||||
GNAVersionSerializer version_;
|
||||
|
||||
void ImportInputs(std::istream &is, void* basePtr, GNAPluginNS::GnaInputs &inputs);
|
||||
|
||||
@@ -47,12 +57,17 @@ private:
|
||||
void AppendTensorNameIfNeeded(GNAPluginNS::GnaDesc& nodeDesc) const;
|
||||
|
||||
public:
|
||||
GNAModelSerial(Gna2Model * model, MemoryType & states_holder)
|
||||
: gna2model_(model), pstates_(&states_holder) {
|
||||
GNAModelSerial(Gna2Model* model, MemoryType& states_holder)
|
||||
: gna2model_(model),
|
||||
pstates_(&states_holder) {
|
||||
}
|
||||
|
||||
GNAModelSerial(Gna2Model * model, GNAPluginNS::GnaInputs &inputs, GNAPluginNS::GnaOutputs &outputs)
|
||||
: gna2model_(model), inputs_(inputs), outputs_(outputs) {
|
||||
GNAModelSerial(Gna2Model* model,
|
||||
GNAPluginNS::GnaInputs& inputs,
|
||||
GNAPluginNS::GnaOutputs& outputs)
|
||||
: gna2model_(model),
|
||||
inputs_(inputs),
|
||||
outputs_(outputs) {
|
||||
}
|
||||
|
||||
void setHeader(GNAPluginNS::HeaderLatest::ModelHeader header) {
|
||||
@@ -103,7 +118,8 @@ private:
|
||||
GNAPluginNS::GnaInputs &inputs,
|
||||
GNAPluginNS::GnaOutputs &outputs,
|
||||
TranspositionInfoMap& inputstranspositionInfo,
|
||||
TranspositionInfoMap& outputstranspositionInfo);
|
||||
TranspositionInfoMap& outputstranspositionInfo,
|
||||
std::string& modelLibVersion);
|
||||
|
||||
/**
|
||||
* save gna graph to an outpus stream
|
||||
|
||||
@@ -1594,6 +1594,7 @@ InferenceEngine::IExecutableNetworkInternal::Ptr GNAPlugin::ImportNetwork(std::i
|
||||
auto header = GNAModelSerial::ReadHeader(networkModel);
|
||||
|
||||
void* basePtr = nullptr;
|
||||
std::string modelLibVersion; //!< OpenVINO and GNA Library versions read from GNA model file
|
||||
|
||||
gnamem->getQueue(REGION_SCRATCH)->reserve_ptr(nullptr, &basePtr, header.gnaMemSize);
|
||||
|
||||
@@ -1603,7 +1604,6 @@ InferenceEngine::IExecutableNetworkInternal::Ptr GNAPlugin::ImportNetwork(std::i
|
||||
GNAModelSerial::MemoryType mt;
|
||||
auto serial = GNAModelSerial(&model->object(), mt);
|
||||
|
||||
|
||||
serial.setHeader(header);
|
||||
serial.Import(basePtr,
|
||||
header.gnaMemSize,
|
||||
@@ -1611,7 +1611,18 @@ InferenceEngine::IExecutableNetworkInternal::Ptr GNAPlugin::ImportNetwork(std::i
|
||||
*(inputs_ptr_),
|
||||
outputs_,
|
||||
transpose_inputs_info,
|
||||
transpose_outputs_info);
|
||||
transpose_outputs_info,
|
||||
modelLibVersion);
|
||||
|
||||
// Print OV and GNA Lib versions used for model export
|
||||
if (gnaFlags->log_level >= ov::log::Level::DEBUG) {
|
||||
if (modelLibVersion.length()) {
|
||||
std::cout << modelLibVersion << std::endl;
|
||||
} else {
|
||||
std::cout << "Unable to read OpenVINO or GNA Library version from model file, consider model export with current "
|
||||
"version of GNA plugin" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
trivialTopology = (model->object().NumberOfOperations == 0);
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "gna_plugin.hpp"
|
||||
#include "ngraph_functions/builders.hpp"
|
||||
#include "common_test_utils/data_utils.hpp"
|
||||
#include "common/versioning.hpp"
|
||||
#include "any_copy.hpp"
|
||||
|
||||
using namespace ::testing;
|
||||
using GNAPluginNS::GNAPlugin;
|
||||
@@ -18,7 +20,7 @@ using namespace InferenceEngine;
|
||||
|
||||
class GNAExportImportTest : public ::testing::Test {
|
||||
public:
|
||||
void ExportModel(std::string exportedModelFileName) {
|
||||
void ExportModel(std::string exportedModelFileName, const ov::AnyMap gnaConfig) {
|
||||
auto function = getFunction();
|
||||
auto weights = make_shared_blob<uint8_t>({ Precision::U8, {1, 10}, Layout::NC });
|
||||
weights->allocate();
|
||||
@@ -29,17 +31,18 @@ public:
|
||||
GNACppApi mockApi;
|
||||
std::vector<std::vector<uint8_t>> data;
|
||||
ExpectEnqueueCalls(&mockApi, data);
|
||||
GNAPlugin plugin(gna_config);
|
||||
GNAPlugin plugin(any_copy(gnaConfig));
|
||||
|
||||
plugin.LoadNetwork(cnnNetwork);
|
||||
plugin.Export(exportedModelFileName);
|
||||
}
|
||||
|
||||
void ImportModel(std::string modelPath) {
|
||||
void ImportModel(std::string modelPath, const ov::AnyMap gnaConfig) {
|
||||
GNACppApi mockApi;
|
||||
std::vector<std::vector<uint8_t>> data;
|
||||
ExpectEnqueueCalls(&mockApi, data);
|
||||
GNAPlugin plugin(gna_config);
|
||||
EXPECT_CALL(mockApi, Gna2RequestWait(_, _)).WillOnce(Return(Gna2StatusSuccess));
|
||||
GNAPlugin plugin(any_copy(gnaConfig));
|
||||
std::fstream inputStream(modelPath, std::ios_base::in | std::ios_base::binary);
|
||||
if (inputStream.fail()) {
|
||||
THROW_GNA_EXCEPTION << "Cannot open file to import model: " << modelPath;
|
||||
@@ -55,6 +58,14 @@ public:
|
||||
plugin.Infer(input, output);
|
||||
}
|
||||
|
||||
std::string ExportImportModelWithLogLevel(const ov::AnyMap gnaConfig) {
|
||||
exported_file_name = "export_test.bin";
|
||||
ExportModel(exported_file_name, gnaConfig);
|
||||
testing::internal::CaptureStdout();
|
||||
ImportModel(exported_file_name, gnaConfig);
|
||||
return testing::internal::GetCapturedStdout();
|
||||
}
|
||||
|
||||
protected:
|
||||
void AllocateInput(BlobMap& input, GNAPlugin *plugin) {
|
||||
auto inputsInfo = plugin->GetNetworkInputs();
|
||||
@@ -147,26 +158,43 @@ protected:
|
||||
void TearDown() override {
|
||||
std::remove(exported_file_name.c_str());
|
||||
}
|
||||
std::map<std::string, std::string> gna_config;
|
||||
std::string exported_file_name;
|
||||
};
|
||||
|
||||
TEST_F(GNAExportImportTest, ExportImportI16) {
|
||||
ov::AnyMap gna_config = {
|
||||
const ov::AnyMap gna_config = {
|
||||
ov::intel_gna::execution_mode(ov::intel_gna::ExecutionMode::SW_EXACT),
|
||||
ov::hint::inference_precision(ngraph::element::i16)
|
||||
};
|
||||
exported_file_name = "export_test.bin";
|
||||
ExportModel(exported_file_name);
|
||||
ImportModel(exported_file_name);
|
||||
ExportModel(exported_file_name, gna_config);
|
||||
ImportModel(exported_file_name, gna_config);
|
||||
}
|
||||
|
||||
TEST_F(GNAExportImportTest, ExportImportI8) {
|
||||
ov::AnyMap gna_config = {
|
||||
const ov::AnyMap gna_config = {
|
||||
ov::intel_gna::execution_mode(ov::intel_gna::ExecutionMode::SW_EXACT),
|
||||
ov::hint::inference_precision(ngraph::element::i8)
|
||||
};
|
||||
exported_file_name = "export_test.bin";
|
||||
ExportModel(exported_file_name);
|
||||
ImportModel(exported_file_name);
|
||||
ExportModel(exported_file_name, gna_config);
|
||||
ImportModel(exported_file_name, gna_config);
|
||||
}
|
||||
|
||||
TEST_F(GNAExportImportTest, HideLibVersionFromModelInLogNoMode) {
|
||||
const ov::AnyMap gna_config = {ov::log::level(ov::log::Level::NO)};
|
||||
EXPECT_THAT(ExportImportModelWithLogLevel(gna_config),
|
||||
Not(HasSubstr(ov::intel_gna::common::get_openvino_version_string())));
|
||||
}
|
||||
|
||||
TEST_F(GNAExportImportTest, HideLibVersionFromModelInLogWarnMode) {
|
||||
const ov::AnyMap gna_config = {ov::log::level(ov::log::Level::WARNING)};
|
||||
EXPECT_THAT(ExportImportModelWithLogLevel(gna_config),
|
||||
Not(HasSubstr(ov::intel_gna::common::get_openvino_version_string())));
|
||||
}
|
||||
|
||||
TEST_F(GNAExportImportTest, ShowLibVersionFromModelInLogDebugMode) {
|
||||
const ov::AnyMap gna_config = {ov::log::level(ov::log::Level::DEBUG)};
|
||||
EXPECT_THAT(ExportImportModelWithLogLevel(gna_config),
|
||||
HasSubstr(ov::intel_gna::common::get_openvino_version_string()));
|
||||
}
|
||||
@@ -8,9 +8,9 @@
|
||||
// to suppress deprecated definition errors
|
||||
#define IMPLEMENT_INFERENCE_ENGINE_PLUGIN
|
||||
#include "gna_model_serial.hpp"
|
||||
#include "common/versioning.hpp"
|
||||
|
||||
using ::testing::Return;
|
||||
using ::testing::_;
|
||||
using namespace testing;
|
||||
|
||||
class IstreamMock final: public std::streambuf {
|
||||
public:
|
||||
@@ -24,3 +24,26 @@ TEST(GNAModelSerialTest, TestErrorOnTellg) {
|
||||
std::istream is(&mock);
|
||||
ASSERT_THROW(GNAModelSerial::ReadHeader(is), InferenceEngine::Exception);
|
||||
}
|
||||
|
||||
TEST(GNAVersionSerializerTest, Export) {
|
||||
std::stringstream sBuf;
|
||||
GNAVersionSerializer verSerializer;
|
||||
verSerializer.Export(sBuf);
|
||||
|
||||
EXPECT_THAT(sBuf.str(), HasSubstr(ov::intel_gna::common::get_openvino_version_string()));
|
||||
}
|
||||
|
||||
TEST(GNAVersionSerializerTest, ImportWhenVersionIsPresent) {
|
||||
std::stringstream sBuf;
|
||||
GNAVersionSerializer verSerializer;
|
||||
verSerializer.Export(sBuf);
|
||||
|
||||
EXPECT_THAT(verSerializer.Import(sBuf), HasSubstr(ov::intel_gna::common::get_openvino_version_string()));
|
||||
}
|
||||
|
||||
TEST(GNAVersionSerializerTest, ImportWhenVersionIsNotPresent) {
|
||||
std::stringstream sBuf;
|
||||
GNAVersionSerializer verSerializer;
|
||||
|
||||
EXPECT_EQ(verSerializer.Import(sBuf).length(), 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user