[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:
Tomasz Adamowicz
2022-10-03 11:49:32 +02:00
committed by GitHub
parent 4f002c46b9
commit 96f474d858
5 changed files with 123 additions and 21 deletions

View File

@@ -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) {

View File

@@ -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

View File

@@ -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);

View File

@@ -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()));
}

View File

@@ -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);
}