From 962df2cdcbb82a6cd824d5228527173c833e4bb7 Mon Sep 17 00:00:00 2001 From: Wang Wangwang Date: Wed, 26 Apr 2023 21:42:53 +0800 Subject: [PATCH] [AUTO] Exclude other vendor's GPU device in default candidate list (#17063) * [AUTO] Plugin takes only Intel dGPU as 1st priority * Update test case * Simplify the code * Support more test cases in GetDeviceList API * Add notIntelGPU to _deviceBlocklist in AUTO plugin * Restore some code formats * Update test cases * Add some logs to GetValidDevice API * Simplify the code --------- Co-authored-by: Wanglei Shen --- src/plugins/auto/src/plugin.cpp | 46 +++++++++-- src/plugins/auto/src/plugin_config.cpp | 2 +- src/plugins/auto/src/plugin_config.hpp | 8 +- .../unit/auto_async_infer_request_test.cpp | 8 ++ .../auto/tests/unit/get_device_list.cpp | 81 ++++++++++++++++++- .../tests/unit/key_network_priority_test.cpp | 27 ++++--- .../auto/tests/unit/select_device_test.cpp | 18 ++++- 7 files changed, 167 insertions(+), 23 deletions(-) diff --git a/src/plugins/auto/src/plugin.cpp b/src/plugins/auto/src/plugin.cpp index c2cdcbacd73..5719d87072b 100644 --- a/src/plugins/auto/src/plugin.cpp +++ b/src/plugins/auto/src/plugin.cpp @@ -549,11 +549,18 @@ std::list MultiDeviceInferencePlugin::GetValidDevice( continue; } if (item.deviceName.find("GPU") == 0) { - auto& gpuUniqueName = item.uniqueName; - if (gpuUniqueName.find("iGPU") != std::string::npos) { + std::string deviceType; + try { + deviceType = GetCore()->GetMetric(item.deviceName, METRIC_KEY(DEVICE_TYPE)).as(); + } catch (const IE::Exception&) { + LOG_DEBUG_TAG("GetMetric:%s for %s failed ", "DEVICE_TYPE", item.deviceName.c_str()); + } + if (deviceType == "integrated") { iGPU.push_back(item); - } else if (gpuUniqueName.find("dGPU") != std::string::npos) { + } else if (deviceType == "discrete") { dGPU.push_back(item); + } else { + LOG_DEBUG_TAG("Unknown device type for %s", item.deviceName.c_str()); } continue; } @@ -674,11 +681,24 @@ void MultiDeviceInferencePlugin::RegisterPriority(const unsigned int& priority, std::string MultiDeviceInferencePlugin::GetDeviceList(const std::map& config) const { std::string allDevices; + std::string deviceArchitecture; auto deviceList = GetCore()->GetAvailableDevices(); auto deviceListConfig = config.find(ov::device::priorities.name()); + auto getGpuArchitecture = [&](const std::string& name) -> std::string { + try { + auto architectureInfo = GetCore()->GetMetric(name, METRIC_KEY(DEVICE_ARCHITECTURE)).as(); + return architectureInfo; + } catch (const IE::Exception&) { + LOG_DEBUG_TAG("GetMetric:%s for %s failed ", "DEVICE_ARCHITECTURE", name.c_str()); + } + return ""; + }; for (auto&& device : deviceList) { // filter out the supported devices - if (!_pluginConfig.isSupportedDevice(device)) + if (device.find("GPU") != std::string::npos) { + deviceArchitecture = getGpuArchitecture(device); + } + if (!_pluginConfig.isSupportedDevice(device, deviceArchitecture)) continue; allDevices += device + ","; } @@ -708,13 +728,27 @@ std::string MultiDeviceInferencePlugin::GetDeviceList(const std::map& devices) { + auto iter = std::find_if(devices.begin(), devices.end(), [device](const std::string& devItem) { + std::string deviceName = device; + std::string::size_type realEndPos = 0; + if ((realEndPos = deviceName.find('.')) != std::string::npos && devItem.find('.') == std::string::npos) { + deviceName = deviceName.substr(0, realEndPos); + } + return devItem.find(deviceName) != std::string::npos; + }); + return iter != devices.end(); + }; auto deviceWithDefaultID = [](std::string& device) { // AUTO assume the default device ID will be "0" for the single device. return device.find(".") == std::string::npos ? device + ".0" : device; }; if (devicesToBeMerged.empty()) { for (auto&& device : deviceList) { - if (isAnyDev(device, devicesToBeDeleted) || !_pluginConfig.isSupportedDevice(device)) + if (device.find("GPU") != std::string::npos) { + deviceArchitecture = getGpuArchitecture(device); + } + if (isAnyDevWithEmptyMerged(device, devicesToBeDeleted) || !_pluginConfig.isSupportedDevice(device, deviceArchitecture)) continue; devicesMerged.push_back(device); } @@ -749,8 +783,6 @@ std::string MultiDeviceInferencePlugin::GetDeviceList(const std::map PluginConfig::_deviceBlocklist = {"VPUX", "GNA"}; +const std::set PluginConfig::_deviceBlocklist = {"VPUX", "GNA", "notIntelGPU"}; PluginConfig::PluginConfig() { set_default(); diff --git a/src/plugins/auto/src/plugin_config.hpp b/src/plugins/auto/src/plugin_config.hpp index 5ddf3fc0f87..4d67b0ebd07 100644 --- a/src/plugins/auto/src/plugin_config.hpp +++ b/src/plugins/auto/src/plugin_config.hpp @@ -183,7 +183,7 @@ public: return pluginName == "AUTO" ? supported_metrics : multi_supported_metrics; } - bool isSupportedDevice(const std::string& deviceName) const { + bool isSupportedDevice(const std::string& deviceName, const std::string& option) const { if (deviceName.empty()) return false; auto realDevName = deviceName[0] != '-' ? deviceName : deviceName.substr(1); @@ -191,6 +191,12 @@ public: return false; } realDevName = ov::DeviceIDParser(realDevName).get_device_name(); + if (realDevName.find("GPU") != std::string::npos) { + // Check if the device is an Intel device + if (option.find("vendor=0x8086") == std::string::npos) { + realDevName = "notIntelGPU"; + } + } std::string::size_type realEndPos = 0; if ((realEndPos = realDevName.find('(')) != std::string::npos) { realDevName = realDevName.substr(0, realEndPos); diff --git a/src/plugins/auto/tests/unit/auto_async_infer_request_test.cpp b/src/plugins/auto/tests/unit/auto_async_infer_request_test.cpp index 0d78b4f25cb..d33c0e0ce73 100644 --- a/src/plugins/auto/tests/unit/auto_async_infer_request_test.cpp +++ b/src/plugins/auto/tests/unit/auto_async_infer_request_test.cpp @@ -16,6 +16,14 @@ std::string AsyncInferenceTest::getTestCaseName(testing::TestParamInfo testDevs = {CommonTestUtils::DEVICE_GPU}; ON_CALL(*core, GetAvailableDevices()).WillByDefault(Return(testDevs)); diff --git a/src/plugins/auto/tests/unit/get_device_list.cpp b/src/plugins/auto/tests/unit/get_device_list.cpp index 5aae145e52b..143e64ccf96 100644 --- a/src/plugins/auto/tests/unit/get_device_list.cpp +++ b/src/plugins/auto/tests/unit/get_device_list.cpp @@ -26,6 +26,9 @@ using ::testing::ReturnRef; using ::testing::NiceMock; using ::testing::AtLeast; using ::testing::InvokeWithoutArgs; +using ::testing::HasSubstr; +using ::testing::StrEq; +using ::testing::_; using Config = std::map; using namespace MockMultiDevice; @@ -91,9 +94,43 @@ TEST_P(GetDeviceListTest, GetDeviceListTestWithExcludeList) { std::tie(priorityDevices, metaDevices) = priorityAndMetaDev; ON_CALL(*core, GetAvailableDevices()).WillByDefault(Return(availableDevs)); + ON_CALL(*core, GetMetric(HasSubstr("GPU"), StrEq(METRIC_KEY(DEVICE_ARCHITECTURE)), _)) + .WillByDefault(Return("GPU: vendor=0x8086 arch=0")); EXPECT_CALL(*core, GetAvailableDevices()).Times(1); - auto result = plugin->GetDeviceList({{ov::device::priorities.name(), priorityDevices}}); - EXPECT_EQ(result, metaDevices); + if (metaDevices == "") { + EXPECT_THROW(plugin->GetDeviceList({{ov::device::priorities.name(), priorityDevices}}), IE::Exception); + } else { + std::string result; + ASSERT_NO_THROW(result = plugin->GetDeviceList({{ov::device::priorities.name(), priorityDevices}})); + EXPECT_EQ(result, metaDevices); + } +} + +using GetDeviceListTestWithNotInteldGPU = GetDeviceListTest; +TEST_P(GetDeviceListTestWithNotInteldGPU, GetDeviceListTestWithExcludeList) { + // get Parameter + Params priorityAndMetaDev; + std::string priorityDevices; + std::string metaDevices; + std::vector availableDevs; + std::tie(availableDevs, priorityAndMetaDev) = this->GetParam(); + std::tie(priorityDevices, metaDevices) = priorityAndMetaDev; + + ON_CALL(*core, GetAvailableDevices()).WillByDefault(Return(availableDevs)); + ON_CALL(*core, GetMetric(StrEq("GPU.1"), StrEq(METRIC_KEY(DEVICE_ARCHITECTURE)), _)) + .WillByDefault(Return("GPU: vendor=0x10DE arch=0")); + ON_CALL(*core, GetMetric(StrEq("GPU.0"), StrEq(METRIC_KEY(DEVICE_ARCHITECTURE)), _)) + .WillByDefault(Return("GPU: vendor=0x8086 arch=0")); + ON_CALL(*core, GetMetric(StrEq("GPU"), StrEq(METRIC_KEY(DEVICE_ARCHITECTURE)), _)) + .WillByDefault(Return("GPU: vendor=0x8086 arch=0")); + EXPECT_CALL(*core, GetAvailableDevices()).Times(1); + if (metaDevices == "") { + EXPECT_THROW(plugin->GetDeviceList({{ov::device::priorities.name(), priorityDevices}}), IE::Exception); + } else { + std::string result; + ASSERT_NO_THROW(result = plugin->GetDeviceList({{ov::device::priorities.name(), priorityDevices}})); + EXPECT_EQ(result, metaDevices); + } } const std::vector testConfigsWithId = {Params{" ", " "}, @@ -113,6 +150,11 @@ const std::vector testConfigsWithId = {Params{" ", " "}, Params{"-GPU.0,-GPU.1", "CPU"}, Params{"-GPU.0,-GPU.1,INVALID_DEVICE", "INVALID_DEVICE"}, Params{"-GPU.0,-GPU.1,-INVALID_DEVICE", "CPU"}, + Params{"-GPU.0,-GPU.1,-CPU", ""}, + Params{"GPU,-GPU.0", "GPU.1"}, + Params{"-GPU,CPU", "CPU"}, + Params{"-GPU,-CPU", ""}, + Params{"GPU.0,-GPU", "GPU.0"}, Params{"-GPU.0,-CPU", "GPU.1"}}; const std::vector testConfigs = {Params{" ", " "}, @@ -139,6 +181,36 @@ const std::vector testConfigs = {Params{" ", " "}, Params{"CPU,-INVALID_DEVICE", "CPU"}, Params{"CPU,GPU,VPUX", "CPU,GPU,VPUX"}}; +const std::vector testConfigsWithIdNotInteldGPU = {Params{" ", " "}, + Params{"", "CPU,GPU.0"}, + Params{"CPU, ", "CPU, "}, + Params{" ,CPU", " ,CPU"}, + Params{"CPU,", "CPU"}, + Params{"CPU,,GPU", "CPU,GPU.0,GPU.1"}, + Params{"CPU, ,GPU", "CPU, ,GPU.0,GPU.1"}, + Params{"CPU,GPU,GPU.1", "CPU,GPU.0,GPU.1"}, + Params{"CPU,GPU,VPUX,INVALID_DEVICE", "CPU,GPU.0,GPU.1,VPUX,INVALID_DEVICE"}, + Params{"VPUX,GPU,CPU,-GPU.0", "VPUX,GPU.1,CPU"}, + Params{"-GPU.0,GPU,CPU", "GPU.1,CPU"}, + Params{"-GPU.0,GPU", "GPU.1"}, + Params{"-GPU,GPU.0", "GPU.0"}, + Params{"-GPU.0", "CPU"}, + Params{"-GPU.0,-GPU.1", "CPU"}, + Params{"-GPU.0,-GPU.1,INVALID_DEVICE", "INVALID_DEVICE"}, + Params{"-GPU.0,-GPU.1,-INVALID_DEVICE", "CPU"}, + Params{"-GPU.0,-GPU.1,-CPU", ""}, + Params{"GPU,-GPU.0", "GPU.1"}, + Params{"GPU.0,-GPU", "GPU.0"}, + Params{"GPU", "GPU.0,GPU.1"}, + Params{"GPU.0", "GPU.0"}, + Params{"GPU.1", "GPU.1"}, + Params{"-CPU", "GPU.0"}, + Params{"-CPU,-GPU", ""}, + Params{"-CPU,-GPU.0", ""}, + Params{"-CPU,-GPU.1", "GPU.0"}, + Params{"-GPU,CPU", "CPU"}, + Params{"-GPU.0,-CPU", ""}}; + INSTANTIATE_TEST_SUITE_P(smoke_Auto_BehaviorTests_GetDeviceListWithID, GetDeviceListTest, ::testing::Combine(::testing::Values(availableDevsWithId), @@ -150,5 +222,10 @@ INSTANTIATE_TEST_SUITE_P(smoke_Auto_BehaviorTests_GetDeviceList, ::testing::Combine(::testing::Values(availableDevs), ::testing::ValuesIn(testConfigs)), GetDeviceListTest::getTestCaseName); +INSTANTIATE_TEST_SUITE_P(smoke_Auto_BehaviorTests_GetDeviceListNotInteldGPU, + GetDeviceListTestWithNotInteldGPU, + ::testing::Combine(::testing::Values(availableDevsWithId), ::testing::ValuesIn(testConfigsWithIdNotInteldGPU)), + GetDeviceListTestWithNotInteldGPU::getTestCaseName); + //toDo need add test for ParseMetaDevices(_, config) to check device config of //return metaDevices diff --git a/src/plugins/auto/tests/unit/key_network_priority_test.cpp b/src/plugins/auto/tests/unit/key_network_priority_test.cpp index 69c68fc4bd1..f19fd7accdd 100644 --- a/src/plugins/auto/tests/unit/key_network_priority_test.cpp +++ b/src/plugins/auto/tests/unit/key_network_priority_test.cpp @@ -30,6 +30,7 @@ using ::testing::Eq; using ::testing::ReturnRef; using ::testing::AtLeast; using ::testing::InvokeWithoutArgs; +using ::testing::HasSubstr; using Config = std::map; using namespace MockMultiDevice; @@ -88,12 +89,20 @@ public: IE_SET_METRIC(OPTIMIZATION_CAPABILITIES, vpuxCability, {"INT8"}); ON_CALL(*core, GetMetric(StrEq(CommonTestUtils::DEVICE_CPU), StrEq(METRIC_KEY(OPTIMIZATION_CAPABILITIES)), _)).WillByDefault(RETURN_MOCK_VALUE(cpuCability)); - ON_CALL(*core, GetMetric(StrEq(CommonTestUtils::DEVICE_GPU), + ON_CALL(*core, GetMetric(HasSubstr("GPU"), StrEq(METRIC_KEY(OPTIMIZATION_CAPABILITIES)), _)).WillByDefault(RETURN_MOCK_VALUE(gpuCability)); ON_CALL(*core, GetMetric(StrEq("MYRIAD"), StrEq(METRIC_KEY(OPTIMIZATION_CAPABILITIES)), _)).WillByDefault(RETURN_MOCK_VALUE(myriadCability)); ON_CALL(*core, GetMetric(StrEq(CommonTestUtils::DEVICE_KEEMBAY), StrEq(METRIC_KEY(OPTIMIZATION_CAPABILITIES)), _)).WillByDefault(RETURN_MOCK_VALUE(vpuxCability)); + ON_CALL(*core, GetMetric(HasSubstr("GPU"), + StrEq(METRIC_KEY(DEVICE_ARCHITECTURE)), _)).WillByDefault(Return("GPU: vendor=0x8086 arch=0")); + ON_CALL(*core, GetMetric(StrEq("GPU"), + StrEq(METRIC_KEY(DEVICE_TYPE)), _)).WillByDefault(Return(Metrics::DeviceType::integrated)); + ON_CALL(*core, GetMetric(StrEq("GPU.0"), + StrEq(METRIC_KEY(DEVICE_TYPE)), _)).WillByDefault(Return(Metrics::DeviceType::integrated)); + ON_CALL(*core, GetMetric(StrEq("GPU.1"), + StrEq(METRIC_KEY(DEVICE_TYPE)), _)).WillByDefault(Return(Metrics::DeviceType::discrete)); ON_CALL(*plugin, SelectDevice).WillByDefault([this](const std::vector& metaDevices, const std::string& netPrecision, unsigned int Priority) { return plugin->MultiDeviceInferencePlugin::SelectDevice(metaDevices, netPrecision, Priority); @@ -115,14 +124,14 @@ TEST_P(KeyNetworkPriorityTest, SelectDevice) { std::vector resDevInfo; if (enableDevicePriority) { metaDevices = {{CommonTestUtils::DEVICE_CPU, {}, 2, "", "CPU_01", 0}, - {CommonTestUtils::DEVICE_GPU, {}, 2, "01", "iGPU_01", 1}, - {CommonTestUtils::DEVICE_GPU, {}, 2, "01", "dGPU_01", 2}, + {"GPU.0", {}, 2, "01", "iGPU_01", 1}, + {"GPU.1", {}, 2, "01", "dGPU_01", 2}, {"MYRIAD", {}, 2, "01", "MYRIAD_01", 3}, {CommonTestUtils::DEVICE_KEEMBAY, {}, 2, "01", "VPUX_01", 4}}; } else { metaDevices = {{CommonTestUtils::DEVICE_CPU, {}, 2, "", "CPU_01", 0}, - {CommonTestUtils::DEVICE_GPU, {}, 2, "01", "iGPU_01", 0}, - {CommonTestUtils::DEVICE_GPU, {}, 2, "01", "dGPU_01", 0}, + {"GPU.0", {}, 2, "01", "iGPU_01", 0}, + {"GPU.1", {}, 2, "01", "dGPU_01", 0}, {"MYRIAD", {}, 2, "01", "MYRIAD_01", 0}, {CommonTestUtils::DEVICE_KEEMBAY, {}, 2, "01", "VPUX_01", 0}}; } @@ -144,14 +153,14 @@ TEST_P(KeyNetworkPriorityTest, MultiThreadsSelectDevice) { std::vector> futureVect; if (enableDevicePriority) { metaDevices = {{CommonTestUtils::DEVICE_CPU, {}, 2, "", "CPU_01", 0}, - {CommonTestUtils::DEVICE_GPU, {}, 2, "01", "iGPU_01", 1}, - {CommonTestUtils::DEVICE_GPU, {}, 2, "01", "dGPU_01", 2}, + {"GPU.0", {}, 2, "01", "iGPU_01", 1}, + {"GPU.1", {}, 2, "01", "dGPU_01", 2}, {"MYRIAD", {}, 2, "01", "MYRIAD_01", 3}, {CommonTestUtils::DEVICE_KEEMBAY, {}, 2, "01", "VPUX_01", 4}}; } else { metaDevices = {{CommonTestUtils::DEVICE_CPU, {}, 2, "", "CPU_01", 0}, - {CommonTestUtils::DEVICE_GPU, {}, 2, "01", "iGPU_01", 0}, - {CommonTestUtils::DEVICE_GPU, {}, 2, "01", "dGPU_01", 0}, + {"GPU.0", {}, 2, "01", "iGPU_01", 0}, + {"GPU.1", {}, 2, "01", "dGPU_01", 0}, {"MYRIAD", {}, 2, "01", "MYRIAD_01", 0}, {CommonTestUtils::DEVICE_KEEMBAY, {}, 2, "01", "VPUX_01", 0}}; } diff --git a/src/plugins/auto/tests/unit/select_device_test.cpp b/src/plugins/auto/tests/unit/select_device_test.cpp index b87e296fcf9..7e9ad02bab7 100644 --- a/src/plugins/auto/tests/unit/select_device_test.cpp +++ b/src/plugins/auto/tests/unit/select_device_test.cpp @@ -30,6 +30,7 @@ using ::testing::Eq; using ::testing::ReturnRef; using ::testing::AtLeast; using ::testing::InvokeWithoutArgs; +using ::testing::HasSubstr; using Config = std::map; using namespace MockMultiDevice; @@ -43,8 +44,8 @@ using ConfigParams = std::tuple< >; const DeviceInformation CPU_INFO = {CommonTestUtils::DEVICE_CPU, {}, 2, "01", "CPU_01"}; -const DeviceInformation IGPU_INFO = {CommonTestUtils::DEVICE_GPU, {}, 2, "01", "iGPU_01"}; -const DeviceInformation DGPU_INFO = {CommonTestUtils::DEVICE_GPU, {}, 2, "01", "dGPU_01"}; +const DeviceInformation IGPU_INFO = {"GPU.0", {}, 2, "01", "iGPU_01"}; +const DeviceInformation DGPU_INFO = {"GPU.1", {}, 2, "01", "dGPU_01"}; const DeviceInformation MYRIAD_INFO = {"MYRIAD", {}, 2, "01", "MYRIAD_01" }; const DeviceInformation KEEMBAY_INFO = {CommonTestUtils::DEVICE_KEEMBAY, {}, 2, "01", "VPUX_01" }; const std::vector fp32DeviceVector = {DGPU_INFO, IGPU_INFO, CPU_INFO, MYRIAD_INFO}; @@ -238,15 +239,26 @@ public: IE_SET_METRIC(OPTIMIZATION_CAPABILITIES, gpuCability, {"FP32", "FP16", "BATCHED_BLOB", "BIN", "INT8"}); IE_SET_METRIC(OPTIMIZATION_CAPABILITIES, myriadCability, {"FP16"}); IE_SET_METRIC(OPTIMIZATION_CAPABILITIES, vpuxCability, {"INT8"}); + IE_SET_METRIC(DEVICE_ARCHITECTURE, gpuArchitecture, "GPU: vendor=0x8086 arch=0"); + IE_SET_METRIC(DEVICE_TYPE, dGpuType, Metrics::DeviceType::discrete); + IE_SET_METRIC(DEVICE_TYPE, iGpuType, Metrics::DeviceType::integrated); ON_CALL(*core, GetMetric(StrEq(CommonTestUtils::DEVICE_CPU), StrEq(METRIC_KEY(OPTIMIZATION_CAPABILITIES)), _)).WillByDefault(RETURN_MOCK_VALUE(cpuCability)); - ON_CALL(*core, GetMetric(StrEq(CommonTestUtils::DEVICE_GPU), + ON_CALL(*core, GetMetric(HasSubstr("GPU"), StrEq(METRIC_KEY(OPTIMIZATION_CAPABILITIES)), _)).WillByDefault(RETURN_MOCK_VALUE(gpuCability)); ON_CALL(*core, GetMetric(StrEq("MYRIAD"), StrEq(METRIC_KEY(OPTIMIZATION_CAPABILITIES)), _)).WillByDefault(RETURN_MOCK_VALUE(myriadCability)); ON_CALL(*core, GetMetric(StrEq(CommonTestUtils::DEVICE_KEEMBAY), StrEq(METRIC_KEY(OPTIMIZATION_CAPABILITIES)), _)).WillByDefault(RETURN_MOCK_VALUE(vpuxCability)); + ON_CALL(*core, GetMetric(HasSubstr("GPU"), + StrEq(METRIC_KEY(DEVICE_ARCHITECTURE)), _)).WillByDefault(RETURN_MOCK_VALUE(gpuArchitecture)); + ON_CALL(*core, GetMetric(StrEq("GPU"), + StrEq(METRIC_KEY(DEVICE_TYPE)), _)).WillByDefault(RETURN_MOCK_VALUE(iGpuType)); + ON_CALL(*core, GetMetric(StrEq("GPU.0"), + StrEq(METRIC_KEY(DEVICE_TYPE)), _)).WillByDefault(RETURN_MOCK_VALUE(iGpuType)); + ON_CALL(*core, GetMetric(StrEq("GPU.1"), + StrEq(METRIC_KEY(DEVICE_TYPE)), _)).WillByDefault(RETURN_MOCK_VALUE(dGpuType)); ON_CALL(*plugin, SelectDevice).WillByDefault([this](const std::vector& metaDevices, const std::string& netPrecision, unsigned int priority) { return plugin->MultiDeviceInferencePlugin::SelectDevice(metaDevices, netPrecision, priority);