278 lines
16 KiB
C++
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);
|
|
|