diff --git a/inference-engine/src/gna_plugin/frontend/model_quantizer.hpp b/inference-engine/src/gna_plugin/frontend/model_quantizer.hpp index cd15b1c1b13631..a2e638c9d7589b 100644 --- a/inference-engine/src/gna_plugin/frontend/model_quantizer.hpp +++ b/inference-engine/src/gna_plugin/frontend/model_quantizer.hpp @@ -115,7 +115,8 @@ class ModelQuantizer { } } - // looking for infinite loop by using algorithm of compute prefix function, complexity O(N) + // We are looking for infinite loop by using algorithm of compute prefix function, complexity O(N) + // (a part of the Knuth–Morris–Pratt algorithm). std::map prefixFunction; int k = infiniteLoopHistory.size(); for (int i = infiniteLoopHistory.size() - 2; i >= 0; i--) { @@ -128,12 +129,36 @@ class ModelQuantizer { k--; } - if ((infiniteLoopHistory.size() - i) % 2 == 0 && (infiniteLoopHistory.size() - i) / 2 == infiniteLoopHistory.size() - k) { + // The pattern length is a length of a repeating string sequence (it is 2 in the example below). + // concat_14_input_0_reshape#concat_15 + // concat_15_input_1_reshape#add_12 + // add_12#Add_16 + // Reshape_41#add_12 + // add_12#Add_16 + // Reshape_41#add_12 + // + // In the case of pattern length is 1, an infinite loop can be found on 2 consecutive strings. + // To avoid this, we will expect the appearance of 4 equal strings for the case pattern length is 1. + if ((infiniteLoopHistory.size() - i) % 2 == 0 && + (infiniteLoopHistory.size() - i) / 2 == infiniteLoopHistory.size() - k && + ((infiniteLoopHistory.size() - i) / 2 > 1 || + std::distance(infiniteLoopHistory.rbegin(), + std::find_if_not(infiniteLoopHistory.rbegin(), infiniteLoopHistory.rend(), + [&infiniteLoopHistory](const std::string& str) { return str == infiniteLoopHistory.back(); })) > 3)) { + gnalog() << "infiniteLoopPattern:\n"; + for (const auto& s : infiniteLoopPattern) { + gnalog() << "\t " << s << '\n'; + } infiniteLoopPattern.clear(); - int patternLength = (infiniteLoopHistory.size() - i)/2; + int patternLength = (infiniteLoopHistory.size() - i) / 2; + gnalog() << "patternLength: " << patternLength << '\n'; for (int j = 0; j < patternLength; j++) { infiniteLoopPattern.emplace_back(infiniteLoopHistory[infiniteLoopHistory.size() - patternLength + j]); } + gnalog() << "infiniteLoopHistory:\n"; + for (const auto& s : infiniteLoopHistory) { + gnalog() << "\t " << s << '\n'; + } infiniteLoopHistory.clear(); gnalog() << "infinite loop detected\n"; break;