[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 <wanglei.shen@intel.com>
This commit is contained in:
Wang Wangwang
2023-04-26 21:42:53 +08:00
committed by GitHub
parent c8ac7c9b82
commit 962df2cdcb
7 changed files with 167 additions and 23 deletions

View File

@@ -549,11 +549,18 @@ std::list<DeviceInformation> 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<std::string>();
} 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<std::string, std::string>& 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<std::string>();
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<std::string
});
return iter != devices.end();
};
auto isAnyDevWithEmptyMerged = [](std::string& device, const std::vector<std::string>& 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<std::string
}
}
}
}
if (devicesMerged.size()) {
allDevices.clear();
std::for_each(devicesMerged.begin(), devicesMerged.end(), [&allDevices](const std::string& device) {
allDevices += device + ",";

View File

@@ -7,7 +7,7 @@ namespace MultiDevicePlugin {
// AUTO will enable the blocklist if
// 1.No device priority passed to AUTO/MULTI.(eg. core.compile_model(model, "AUTO", configs);)
// 2.No valid device parsed out from device priority (eg. core.compile_model(model, "AUTO:-CPU,-GPU", configs);).
const std::set<std::string> PluginConfig::_deviceBlocklist = {"VPUX", "GNA"};
const std::set<std::string> PluginConfig::_deviceBlocklist = {"VPUX", "GNA", "notIntelGPU"};
PluginConfig::PluginConfig() {
set_default();

View File

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

View File

@@ -16,6 +16,14 @@ std::string AsyncInferenceTest::getTestCaseName(testing::TestParamInfo<AsyncInfe
void AsyncInferenceTest::SetUp() {
std::tie(isCpuFaster, isSingleDevice) = GetParam();
ON_CALL(*core.get(), isNewAPI()).WillByDefault(Return(true));
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(ov::device::Type::INTEGRATED));
ON_CALL(*core, GetMetric(StrEq("GPU.0"),
StrEq(METRIC_KEY(DEVICE_TYPE)), _)).WillByDefault(Return(ov::device::Type::INTEGRATED));
ON_CALL(*core, GetMetric(StrEq("GPU.1"),
StrEq(METRIC_KEY(DEVICE_TYPE)), _)).WillByDefault(Return(ov::device::Type::DISCRETE));
if (isSingleDevice) {
std::vector<std::string> testDevs = {CommonTestUtils::DEVICE_GPU};
ON_CALL(*core, GetAvailableDevices()).WillByDefault(Return(testDevs));

View File

@@ -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<std::string, std::string>;
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<std::string> 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<Params> testConfigsWithId = {Params{" ", " "},
@@ -113,6 +150,11 @@ const std::vector<Params> 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<Params> testConfigs = {Params{" ", " "},
@@ -139,6 +181,36 @@ const std::vector<Params> testConfigs = {Params{" ", " "},
Params{"CPU,-INVALID_DEVICE", "CPU"},
Params{"CPU,GPU,VPUX", "CPU,GPU,VPUX"}};
const std::vector<Params> 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

View File

@@ -30,6 +30,7 @@ using ::testing::Eq;
using ::testing::ReturnRef;
using ::testing::AtLeast;
using ::testing::InvokeWithoutArgs;
using ::testing::HasSubstr;
using Config = std::map<std::string, std::string>;
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<DeviceInformation>& 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<DeviceInformation> 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<std::future<void>> 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}};
}

View File

@@ -30,6 +30,7 @@ using ::testing::Eq;
using ::testing::ReturnRef;
using ::testing::AtLeast;
using ::testing::InvokeWithoutArgs;
using ::testing::HasSubstr;
using Config = std::map<std::string, std::string>;
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<DeviceInformation> 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<DeviceInformation>& metaDevices,
const std::string& netPrecision, unsigned int priority) {
return plugin->MultiDeviceInferencePlugin::SelectDevice(metaDevices, netPrecision, priority);