Files
openvino/inference-engine/tests/unit/auto/auto_select_device_failed_test.cpp
2021-12-06 05:58:05 +03:00

278 lines
16 KiB
C++

// Copyright (C) 2018-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <ie_metric_helpers.hpp>
#include <common_test_utils/test_constants.hpp>
#include "unit_test_utils/mocks/cpp_interfaces/interface/mock_icore.hpp"
#include "unit_test_utils/mocks/mock_iinfer_request.hpp"
#include "unit_test_utils/mocks/cpp_interfaces/impl/mock_inference_plugin_internal.hpp"
#include "unit_test_utils/mocks/cpp_interfaces/interface/mock_iexecutable_network_internal.hpp"
#include "unit_test_utils/mocks/cpp_interfaces/interface/mock_ivariable_state_internal.hpp"
#include "unit_test_utils/mocks/cpp_interfaces/interface/mock_iinference_plugin.hpp"
#include <ie_core.hpp>
#include <multi-device/multi_device_config.hpp>
#include <ngraph_functions/subgraph_builders.hpp>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "plugin/mock_auto_device_plugin.hpp"
#include "cpp/ie_plugin.hpp"
using ::testing::MatcherCast;
using ::testing::AllOf;
using ::testing::Throw;
using ::testing::Matches;
using ::testing::_;
using ::testing::StrEq;
using ::testing::Return;
using ::testing::Property;
using ::testing::Eq;
using ::testing::ReturnRef;
using ::testing::AtLeast;
using ::testing::AnyNumber;
using Config = std::map<std::string, std::string>;
using namespace MockMultiDevice;
#define IE_SET_METRIC(key, name, ...) \
typename ::InferenceEngine::Metrics::MetricType<::InferenceEngine::Metrics::key>::type name = \
__VA_ARGS__;
using DeviceParams = std::tuple<std::string, bool>;
using ConfigParams = std::tuple<
bool, // if can continue to run
bool, // if select throw exception
std::vector<DeviceParams>, // {device, loadSuccess}
unsigned int, // select count
unsigned int, // load count
unsigned int // load device success count
>;
class AutoLoadFailedTest : public ::testing::TestWithParam<ConfigParams> {
public:
std::shared_ptr<ngraph::Function> function;
InferenceEngine::CNNNetwork cnnNet;
std::shared_ptr<MockICore> core;
std::shared_ptr<MockMultiDeviceInferencePlugin> plugin;
//mock exeNetwork
std::shared_ptr<MockIExecutableNetworkInternal> mockIExeNet;
ov::runtime::SoPtr<IExecutableNetworkInternal> mockExeNetwork;
MockIInferencePlugin* mockIPlugin;
InferenceEngine::InferencePlugin mockPlugin;
// config for Auto device
std::map<std::string, std::string> config;
std::vector<DeviceInformation> metaDevices;
std::shared_ptr<MockIInferRequestInternal> inferReqInternal;
public:
static std::string getTestCaseName(testing::TestParamInfo<ConfigParams> obj) {
unsigned int selectCount;
unsigned int loadCount;
unsigned int loadSuccessCount;
std::vector<std::tuple<std::string, bool>> deviceConfigs;
bool continueRun;
bool thrExcWheSelect;
std::tie(continueRun, thrExcWheSelect, deviceConfigs,
selectCount, loadCount, loadSuccessCount) = obj.param;
std::ostringstream result;
for (auto& item : deviceConfigs) {
if (std::get<1>(item)) {
result << std::get<0>(item) << "_success_";
} else {
result << std::get<0>(item) << "_failed_";
}
}
if (thrExcWheSelect) {
result << "select_failed_";
} else {
result << "select_success_";
}
result << "select_" << selectCount << "_loadCount_"
<< loadCount << "_loadSuccessCount_" << loadSuccessCount;
return result.str();
}
void TearDown() override {
core.reset();
plugin.reset();
mockIExeNet.reset();
mockExeNetwork = {};
mockPlugin = {};
config.clear();
metaDevices.clear();
inferReqInternal.reset();
}
void SetUp() override {
// prepare mockExeNetwork
mockIExeNet = std::make_shared<MockIExecutableNetworkInternal>();
auto mockIPluginPtr = std::make_shared<MockIInferencePlugin>();
ON_CALL(*mockIPluginPtr, LoadNetwork(MatcherCast<const CNNNetwork&>(_), _)).WillByDefault(Return(mockIExeNet));
mockPlugin = InferenceEngine::InferencePlugin{{}, mockIPluginPtr};
// remove annoying ON CALL message
EXPECT_CALL(*mockIPluginPtr, LoadNetwork(MatcherCast<const CNNNetwork&>(_), _)).Times(1);
mockExeNetwork = mockPlugin.LoadNetwork(CNNNetwork{}, {});
// prepare mockicore and cnnNetwork for loading
core = std::shared_ptr<MockICore>(new MockICore());
auto* origin_plugin = new MockMultiDeviceInferencePlugin();
plugin = std::shared_ptr<MockMultiDeviceInferencePlugin>(origin_plugin);
function = ngraph::builder::subgraph::makeConvPoolRelu();
cnnNet = InferenceEngine::CNNNetwork(function);
// replace core with mock Icore
plugin->SetCore(core);
// mock execNetwork can work
inferReqInternal = std::make_shared<MockIInferRequestInternal>();
ON_CALL(*mockIExeNet.get(), CreateInferRequest()).WillByDefault(Return(inferReqInternal));
IE_SET_METRIC(OPTIMAL_NUMBER_OF_INFER_REQUESTS, optimalNum, 2);
ON_CALL(*mockIExeNet.get(), GetMetric(StrEq(METRIC_KEY(OPTIMAL_NUMBER_OF_INFER_REQUESTS))))
.WillByDefault(Return(optimalNum));
IE_SET_METRIC(SUPPORTED_CONFIG_KEYS, supportConfigs, {});
ON_CALL(*core, GetMetric(_, StrEq(METRIC_KEY(SUPPORTED_CONFIG_KEYS)), _))
.WillByDefault(Return(supportConfigs));
EXPECT_CALL(*core, GetMetric(_, StrEq(METRIC_KEY(SUPPORTED_CONFIG_KEYS)), _)).Times(AnyNumber());
}
};
TEST_P(AutoLoadFailedTest, LoadCNNetWork) {
// get Parameter
unsigned int selectCount;
unsigned int loadCount;
unsigned int loadSuccessCount;
std::vector<std::tuple<std::string, bool>> deviceConfigs;
bool continueRun;
bool thrExcWheSelect;
std::tie(continueRun, thrExcWheSelect, deviceConfigs, selectCount,
loadCount, loadSuccessCount) = this->GetParam();
// test auto plugin
config.insert({CONFIG_KEY_INTERNAL(MULTI_WORK_MODE_AS_AUTO), InferenceEngine::PluginConfigParams::YES});
std::string devicesStr = "";
int selDevsSize = deviceConfigs.size();
for (auto iter = deviceConfigs.begin(); iter != deviceConfigs.end(); selDevsSize--) {
std::string deviceName = std::get<0>(*iter);
bool loadSuccess = std::get<1>(*iter);
// accoding to device loading config, set if the loading will successful or throw exception.
if (loadSuccess) {
ON_CALL(*core, LoadNetwork(::testing::Matcher<const InferenceEngine::CNNNetwork&>(_),
::testing::Matcher<const std::string&>(StrEq(deviceName)),
::testing::Matcher<const Config&>(_))).WillByDefault(Return(mockExeNetwork));
} else {
ON_CALL(*core, LoadNetwork(::testing::Matcher<const InferenceEngine::CNNNetwork&>(_),
::testing::Matcher<const std::string&>(StrEq(deviceName)),
::testing::Matcher<const Config&>(_)))
.WillByDefault(Throw(InferenceEngine::GeneralError{""}));
}
DeviceInformation devInfo = {deviceName, {}, 2, ""};
metaDevices.push_back(std::move(devInfo));
// set the return value of SelectDevice
// for example if there are three device, if will return GPU on the first call, and then MYRIAD
// at last CPU
ON_CALL(*plugin, SelectDevice(Property(&std::vector<DeviceInformation>::size, Eq(selDevsSize)), _))
.WillByDefault(Return(metaDevices[deviceConfigs.size() - selDevsSize]));
devicesStr += deviceName;
devicesStr += ((++iter) == deviceConfigs.end()) ? "" : ",";
}
ON_CALL(*plugin, ParseMetaDevices(_, _)).WillByDefault(Return(metaDevices));
config.insert({InferenceEngine::MultiDeviceConfigParams::KEY_MULTI_DEVICE_PRIORITIES , devicesStr});
// if set this parameter true, the second selecting call will thrown exception,
// if there is only one device, it will thrown exception at the first call
if (thrExcWheSelect) {
selDevsSize = deviceConfigs.size();
if (selDevsSize > 1) {
ON_CALL(*plugin, SelectDevice(Property(&std::vector<DeviceInformation>::size, Eq(selDevsSize - 1)), _))
.WillByDefault(Throw(InferenceEngine::GeneralError{""}));
} else {
ON_CALL(*plugin, SelectDevice(Property(&std::vector<DeviceInformation>::size, Eq(1)), _))
.WillByDefault(Throw(InferenceEngine::GeneralError{""}));
}
}
EXPECT_CALL(*plugin, ParseMetaDevices(_, _)).Times(AtLeast(1));
EXPECT_CALL(*plugin, SelectDevice(_, _)).Times(selectCount);
EXPECT_CALL(*core, LoadNetwork(::testing::Matcher<const InferenceEngine::CNNNetwork&>(_),
::testing::Matcher<const std::string&>(_),
::testing::Matcher<const Config&>(_))).Times(loadCount);
// if loadSuccess will get the optimalNum requset of per device, in this test is 2;
EXPECT_CALL(*mockIExeNet.get(), GetMetric(StrEq(METRIC_KEY(OPTIMAL_NUMBER_OF_INFER_REQUESTS))))
.Times(loadSuccessCount);
EXPECT_CALL(*inferReqInternal, SetCallback(_)).Times(loadSuccessCount * 2);
EXPECT_CALL(*mockIExeNet.get(), CreateInferRequest()).Times(loadSuccessCount * 2);
if (continueRun) {
ASSERT_NO_THROW(plugin->LoadExeNetworkImpl(cnnNet, config));
} else {
ASSERT_THROW(plugin->LoadExeNetworkImpl(cnnNet, config), InferenceEngine::Exception);
}
}
// the test configure, for example
// ConfigParams {true, false, {DeviceParams {CommonTestUtils::DEVICE_GPU, false},
// DeviceParams {CommonTestUtils::DEVICE_MYRIAD, true},
// DeviceParams {CommonTestUtils::DEVICE_CPU, true}}, 2, 3, 2},
//
// every element for ConfigParams
// {continueRun, selectThrowException, deviceLoadsuccessVector, selectCount, loadCount, loadSuccessCount}
// { true, false, 3 device, 2, 3, 2}
//
// there are three devices for loading
// CPU load for accelerator success, but GPU will load faild and then select MYRIAD and load again
// LoadExeNetworkImpl will not throw exception and can continue to run,
// it will select twice, first select GPU, second select MYRIAD
// it will load network three times(CPU, GPU, MYRIAD)
// the inference request num is loadSuccessCount * optimalNum, in this test case optimalNum is 2
// so inference request num is 4 (CPU 2, MYRIAD 2)
//
const std::vector<ConfigParams> testConfigs = {ConfigParams {true, false, {DeviceParams {CommonTestUtils::DEVICE_GPU, true},
DeviceParams {CommonTestUtils::DEVICE_MYRIAD, true},
DeviceParams {CommonTestUtils::DEVICE_CPU, true}}, 1, 2, 2},
ConfigParams {true, false, {DeviceParams {CommonTestUtils::DEVICE_GPU, false},
DeviceParams {CommonTestUtils::DEVICE_MYRIAD, true},
DeviceParams {CommonTestUtils::DEVICE_CPU, true}}, 2, 3, 2},
ConfigParams {true, false, {DeviceParams {CommonTestUtils::DEVICE_GPU, true},
DeviceParams {CommonTestUtils::DEVICE_MYRIAD, false},
DeviceParams {CommonTestUtils::DEVICE_CPU, true}}, 1, 2, 2},
ConfigParams {true, false, {DeviceParams {CommonTestUtils::DEVICE_GPU, true},
DeviceParams {CommonTestUtils::DEVICE_MYRIAD, true},
DeviceParams {CommonTestUtils::DEVICE_CPU, false}}, 1, 2, 1},
ConfigParams {true, false, {DeviceParams {CommonTestUtils::DEVICE_GPU, true},
DeviceParams {CommonTestUtils::DEVICE_MYRIAD, false},
DeviceParams {CommonTestUtils::DEVICE_CPU, false}}, 1, 2, 1},
ConfigParams {true, false, {DeviceParams {CommonTestUtils::DEVICE_GPU, false},
DeviceParams {CommonTestUtils::DEVICE_MYRIAD, true},
DeviceParams {CommonTestUtils::DEVICE_CPU, false}}, 2, 3, 1},
ConfigParams {true, false, {DeviceParams {CommonTestUtils::DEVICE_GPU, false},
DeviceParams {CommonTestUtils::DEVICE_MYRIAD, false},
DeviceParams {CommonTestUtils::DEVICE_CPU, true}}, 3, 3, 1},
ConfigParams {false, false, {DeviceParams {CommonTestUtils::DEVICE_GPU, false},
DeviceParams {CommonTestUtils::DEVICE_MYRIAD, false},
DeviceParams {CommonTestUtils::DEVICE_CPU, false}}, 3, 3, 0},
ConfigParams {true, false, {DeviceParams {CommonTestUtils::DEVICE_GPU, true},
DeviceParams {CommonTestUtils::DEVICE_CPU, true}}, 1, 2, 2},
ConfigParams {true, false, {DeviceParams {CommonTestUtils::DEVICE_GPU, false},
DeviceParams {CommonTestUtils::DEVICE_CPU, true}}, 2, 2, 1},
ConfigParams {true, false, {DeviceParams {CommonTestUtils::DEVICE_GPU, true},
DeviceParams {CommonTestUtils::DEVICE_CPU, false}}, 1, 2, 1},
ConfigParams {false, false, {DeviceParams {CommonTestUtils::DEVICE_GPU, false},
DeviceParams {CommonTestUtils::DEVICE_CPU, false}}, 2, 2, 0},
ConfigParams {false, false, {DeviceParams {CommonTestUtils::DEVICE_GPU, false}}, 1, 1, 0},
ConfigParams {false, false, {DeviceParams {CommonTestUtils::DEVICE_CPU, false}}, 1, 1, 0},
ConfigParams {true, false, {DeviceParams {CommonTestUtils::DEVICE_GPU, true}}, 1, 1, 1},
ConfigParams {true, false, {DeviceParams {CommonTestUtils::DEVICE_CPU, true}}, 1, 1, 1},
ConfigParams {false, true, {DeviceParams {CommonTestUtils::DEVICE_GPU, true}}, 1, 0, 0},
ConfigParams {false, true, {DeviceParams {CommonTestUtils::DEVICE_CPU, true}}, 1, 0, 0},
ConfigParams {true, true, {DeviceParams {CommonTestUtils::DEVICE_GPU, false},
DeviceParams {CommonTestUtils::DEVICE_MYRIAD, true},
DeviceParams {CommonTestUtils::DEVICE_CPU, true}}, 2, 2, 1},
ConfigParams {false, true, {DeviceParams {CommonTestUtils::DEVICE_GPU, false},
DeviceParams {CommonTestUtils::DEVICE_MYRIAD, true},
DeviceParams {CommonTestUtils::DEVICE_CPU, false}}, 2, 2, 0},
ConfigParams {true, true, {DeviceParams {CommonTestUtils::DEVICE_GPU, false},
DeviceParams {CommonTestUtils::DEVICE_CPU, true}}, 2, 2, 1}
};
INSTANTIATE_TEST_SUITE_P(smoke_Auto_BehaviorTests, AutoLoadFailedTest,
::testing::ValuesIn(testConfigs),
AutoLoadFailedTest::getTestCaseName);