From 0c1282ab823c313ab144325b0968f59841c2b7de Mon Sep 17 00:00:00 2001 From: Jaime Arteaga Date: Sat, 11 Apr 2020 16:07:22 -0700 Subject: [PATCH] Add levelZeroSupported field to RuntimeCapabilityTable So initialization fails gracefully when Level Zero is executed in unsupported platforms. Change-Id: I06bd9f00260ebb1266108bd4ccee7abbc9275200 Signed-off: Jaime Arteaga --- .../core/source/driver/driver_handle_imp.cpp | 34 ++++--- level_zero/core/test/unit_tests/main.cpp | 14 ++- .../unit_tests/sources/driver/test_driver.cpp | 99 ++++++++++++++++++- level_zero/tools/test/unit_tests/main.cpp | 14 ++- opencl/source/gen11/hw_info_ehl.inl | 3 +- opencl/source/gen11/hw_info_icllp.inl | 3 +- opencl/source/gen11/hw_info_lkf.inl | 3 +- opencl/source/gen12lp/hw_info_tgllp.inl | 3 +- opencl/source/gen8/hw_info_bdw.inl | 3 +- opencl/source/gen9/hw_info_bxt.inl | 3 +- opencl/source/gen9/hw_info_cfl.inl | 3 +- opencl/source/gen9/hw_info_glk.inl | 3 +- opencl/source/gen9/hw_info_kbl.inl | 3 +- opencl/source/gen9/hw_info_skl.inl | 3 +- shared/source/helpers/hw_info.h | 1 + 15 files changed, 161 insertions(+), 31 deletions(-) diff --git a/level_zero/core/source/driver/driver_handle_imp.cpp b/level_zero/core/source/driver/driver_handle_imp.cpp index 1f59263370..d51c36e64b 100644 --- a/level_zero/core/source/driver/driver_handle_imp.cpp +++ b/level_zero/core/source/driver/driver_handle_imp.cpp @@ -113,23 +113,33 @@ DriverHandleImp::~DriverHandleImp() { } ze_result_t DriverHandleImp::initialize(std::vector> devices) { - this->memoryManager = devices[0]->getMemoryManager(); - if (this->memoryManager == nullptr) { - return ZE_RESULT_ERROR_UNINITIALIZED; - } - - this->svmAllocsManager = new NEO::SVMAllocsManager(memoryManager); - if (this->svmAllocsManager == nullptr) { - return ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY; - } - - this->numDevices = static_cast(devices.size()); - for (auto &neoDevice : devices) { + if (!neoDevice->getHardwareInfo().capabilityTable.levelZeroSupported) { + continue; + } + + if (this->memoryManager == nullptr) { + this->memoryManager = neoDevice->getMemoryManager(); + if (this->memoryManager == nullptr) { + return ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY; + } + + this->svmAllocsManager = new NEO::SVMAllocsManager(memoryManager); + if (this->svmAllocsManager == nullptr) { + return ZE_RESULT_ERROR_OUT_OF_HOST_MEMORY; + } + } + auto device = Device::create(this, neoDevice.release()); this->devices.push_back(device); } + if (this->devices.size() == 0) { + return ZE_RESULT_ERROR_UNINITIALIZED; + } + + this->numDevices = static_cast(this->devices.size()); + extensionFunctionsLookupMap = getExtensionFunctionsLookupMap(); return ZE_RESULT_SUCCESS; diff --git a/level_zero/core/test/unit_tests/main.cpp b/level_zero/core/test/unit_tests/main.cpp index a16c51da55..4f899532be 100644 --- a/level_zero/core/test/unit_tests/main.cpp +++ b/level_zero/core/test/unit_tests/main.cpp @@ -160,14 +160,20 @@ int main(int argc, char **argv) { } } if (productFamily == IGFX_UNKNOWN) { - std::cout << "unknown or unsupported product family has been set: " << argv[i] + std::cout << "unknown product family has been set: " << argv[i] << std::endl; return -1; - } else { - std::cout << "product family: " << NEO::hardwarePrefix[productFamily] << " (" - << productFamily << ")" << std::endl; } + hwInfoForTests = *NEO::hardwareInfoTable[productFamily]; + if (!hwInfoForTests.capabilityTable.levelZeroSupported) { + std::cout << "unsupported product family has been set: " << argv[i] + << std::endl; + return 0; + } + + std::cout << "product family: " << NEO::hardwarePrefix[productFamily] << " (" + << productFamily << ")" << std::endl; } } if (!strcmp("--disable_default_listener", argv[i])) { diff --git a/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp b/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp index c467c68b34..c01437679c 100644 --- a/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp +++ b/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp @@ -5,6 +5,10 @@ * */ +#include "shared/source/os_interface/device_factory.h" +#include "shared/source/os_interface/hw_info_config.h" +#include "shared/test/unit_test/helpers/debug_manager_state_restore.h" + #include "test.h" #include "level_zero/core/source/driver/driver_handle_imp.h" @@ -29,5 +33,98 @@ TEST_F(DriverVersionTest, returnsExpectedDriverVersion) { EXPECT_EQ(static_cast(strtoul(NEO_VERSION_BUILD, NULL, 10)), versionBuild); } +TEST(DriverTestFamilySupport, whenInitializingDriverOnSupportedFamilyThenDriverIsCreated) { + NEO::HardwareInfo hwInfo = *NEO::defaultHwInfo.get(); + hwInfo.capabilityTable.levelZeroSupported = true; + + NEO::MockDevice *neoDevice = NEO::MockDevice::createWithNewExecutionEnvironment(&hwInfo); + NEO::DeviceVector devices; + devices.push_back(std::unique_ptr(neoDevice)); + + auto driverHandle = DriverHandle::create(std::move(devices)); + EXPECT_NE(nullptr, driverHandle); + delete driverHandle; +} + +TEST(DriverTestFamilySupport, whenInitializingDriverOnNotSupportedFamilyThenDriverIsNotCreated) { + NEO::HardwareInfo hwInfo = *NEO::defaultHwInfo.get(); + hwInfo.capabilityTable.levelZeroSupported = false; + + NEO::MockDevice *neoDevice = NEO::MockDevice::createWithNewExecutionEnvironment(&hwInfo); + NEO::DeviceVector devices; + devices.push_back(std::unique_ptr(neoDevice)); + + auto driverHandle = DriverHandle::create(std::move(devices)); + EXPECT_EQ(nullptr, driverHandle); +} + +struct DriverTestMultipleFamilySupport : public ::testing::Test { + void SetUp() override { + VariableBackup mockDeviceFlagBackup(&MockDevice::createSingleDevice, false); + + NEO::ExecutionEnvironment *executionEnvironment = new NEO::ExecutionEnvironment(); + executionEnvironment->prepareRootDeviceEnvironments(numRootDevices); + for (auto i = 0u; i < executionEnvironment->rootDeviceEnvironments.size(); i++) { + executionEnvironment->rootDeviceEnvironments[i]->setHwInfo(NEO::defaultHwInfo.get()); + } + + for (auto i = 0u; i < executionEnvironment->rootDeviceEnvironments.size(); i++) { + devices.push_back(std::unique_ptr(NEO::MockDevice::createWithExecutionEnvironment(NEO::defaultHwInfo.get(), executionEnvironment, i))); + if (i < numSupportedRootDevices) { + devices[i]->getRootDeviceEnvironment().getMutableHardwareInfo()->capabilityTable.levelZeroSupported = true; + } else { + devices[i]->getRootDeviceEnvironment().getMutableHardwareInfo()->capabilityTable.levelZeroSupported = false; + } + } + } + + DebugManagerStateRestore restorer; + std::vector> devices; + + const uint32_t numRootDevices = 3u; + const uint32_t numSupportedRootDevices = 2u; +}; + +TEST_F(DriverTestMultipleFamilySupport, whenInitializingDriverWithArrayOfDevicesThenDriverIsInitializedOnlyWithThoseSupported) { + auto driverHandle = DriverHandle::create(std::move(devices)); + EXPECT_NE(nullptr, driverHandle); + + L0::DriverHandleImp *driverHandleImp = reinterpret_cast(driverHandle); + EXPECT_EQ(numSupportedRootDevices, driverHandleImp->devices.size()); + + for (auto d : driverHandleImp->devices) { + EXPECT_TRUE(d->getNEODevice()->getHardwareInfo().capabilityTable.levelZeroSupported); + } + + delete driverHandle; +} + +struct DriverTestMultipleFamilyNoSupport : public ::testing::Test { + void SetUp() override { + VariableBackup mockDeviceFlagBackup(&MockDevice::createSingleDevice, false); + + NEO::ExecutionEnvironment *executionEnvironment = new NEO::ExecutionEnvironment(); + executionEnvironment->prepareRootDeviceEnvironments(numRootDevices); + for (auto i = 0u; i < executionEnvironment->rootDeviceEnvironments.size(); i++) { + executionEnvironment->rootDeviceEnvironments[i]->setHwInfo(NEO::defaultHwInfo.get()); + } + + for (auto i = 0u; i < executionEnvironment->rootDeviceEnvironments.size(); i++) { + devices.push_back(std::unique_ptr(NEO::MockDevice::createWithExecutionEnvironment(NEO::defaultHwInfo.get(), executionEnvironment, i))); + devices[i]->getRootDeviceEnvironment().getMutableHardwareInfo()->capabilityTable.levelZeroSupported = false; + } + } + + DebugManagerStateRestore restorer; + std::vector> devices; + + const uint32_t numRootDevices = 3u; +}; + +TEST_F(DriverTestMultipleFamilyNoSupport, whenInitializingDriverWithArrayOfNotSupportedDevicesThenDriverIsNull) { + auto driverHandle = DriverHandle::create(std::move(devices)); + EXPECT_EQ(nullptr, driverHandle); +} + } // namespace ult -} // namespace L0 \ No newline at end of file +} // namespace L0 diff --git a/level_zero/tools/test/unit_tests/main.cpp b/level_zero/tools/test/unit_tests/main.cpp index bb357dd438..74181df277 100644 --- a/level_zero/tools/test/unit_tests/main.cpp +++ b/level_zero/tools/test/unit_tests/main.cpp @@ -138,14 +138,20 @@ int main(int argc, char **argv) { } } if (productFamily == IGFX_UNKNOWN) { - std::cout << "unknown or unsupported product family has been set: " << argv[i] + std::cout << "unknown product family has been set: " << argv[i] << std::endl; return -1; - } else { - std::cout << "product family: " << NEO::hardwarePrefix[productFamily] << " (" - << productFamily << ")" << std::endl; } + hwInfoForTests = *NEO::hardwareInfoTable[productFamily]; + if (!hwInfoForTests.capabilityTable.levelZeroSupported) { + std::cout << "unsupported product family has been set: " << argv[i] + << std::endl; + return 0; + } + + std::cout << "product family: " << NEO::hardwarePrefix[productFamily] << " (" + << productFamily << ")" << std::endl; } } if (!strcmp("--disable_default_listener", argv[i])) { diff --git a/opencl/source/gen11/hw_info_ehl.inl b/opencl/source/gen11/hw_info_ehl.inl index b2b282900d..3bf7fe45f2 100644 --- a/opencl/source/gen11/hw_info_ehl.inl +++ b/opencl/source/gen11/hw_info_ehl.inl @@ -72,7 +72,8 @@ const RuntimeCapabilityTable EHL::capabilityTable{ true, // supportsDeviceEnqueue false, // supportsPipes false, // supportsOcl21Features - true // hostPtrTrackingEnabled + true, // hostPtrTrackingEnabled + false // levelZeroSupported }; WorkaroundTable EHL::workaroundTable = {}; diff --git a/opencl/source/gen11/hw_info_icllp.inl b/opencl/source/gen11/hw_info_icllp.inl index bf78a898b0..49672d5048 100644 --- a/opencl/source/gen11/hw_info_icllp.inl +++ b/opencl/source/gen11/hw_info_icllp.inl @@ -73,7 +73,8 @@ const RuntimeCapabilityTable ICLLP::capabilityTable{ true, // supportsDeviceEnqueue true, // supportsPipes true, // supportsOcl21Features - true // hostPtrTrackingEnabled + true, // hostPtrTrackingEnabled + true // levelZeroSupported }; WorkaroundTable ICLLP::workaroundTable = {}; diff --git a/opencl/source/gen11/hw_info_lkf.inl b/opencl/source/gen11/hw_info_lkf.inl index 69bec3dae0..6aa3009fdd 100644 --- a/opencl/source/gen11/hw_info_lkf.inl +++ b/opencl/source/gen11/hw_info_lkf.inl @@ -72,7 +72,8 @@ const RuntimeCapabilityTable LKF::capabilityTable{ true, // supportsDeviceEnqueue false, // supportsPipes false, // supportsOcl21Features - true // hostPtrTrackingEnabled + true, // hostPtrTrackingEnabled + false // levelZeroSupported }; WorkaroundTable LKF::workaroundTable = {}; diff --git a/opencl/source/gen12lp/hw_info_tgllp.inl b/opencl/source/gen12lp/hw_info_tgllp.inl index 903724c867..685b0365da 100644 --- a/opencl/source/gen12lp/hw_info_tgllp.inl +++ b/opencl/source/gen12lp/hw_info_tgllp.inl @@ -74,7 +74,8 @@ const RuntimeCapabilityTable TGLLP::capabilityTable{ true, // supportsDeviceEnqueue false, // supportsPipes true, // supportsOcl21Features - false // hostPtrTrackingEnabled + false, // hostPtrTrackingEnabled + true // levelZeroSupported }; WorkaroundTable TGLLP::workaroundTable = {}; diff --git a/opencl/source/gen8/hw_info_bdw.inl b/opencl/source/gen8/hw_info_bdw.inl index 616c066f00..82701a73d0 100644 --- a/opencl/source/gen8/hw_info_bdw.inl +++ b/opencl/source/gen8/hw_info_bdw.inl @@ -77,7 +77,8 @@ const RuntimeCapabilityTable BDW::capabilityTable{ true, // supportsDeviceEnqueue true, // supportsPipes true, // supportsOcl21Features - true // hostPtrTrackingEnabled + true, // hostPtrTrackingEnabled + false // levelZeroSupported }; WorkaroundTable BDW::workaroundTable = {}; diff --git a/opencl/source/gen9/hw_info_bxt.inl b/opencl/source/gen9/hw_info_bxt.inl index 4ef04a2768..434a342b00 100644 --- a/opencl/source/gen9/hw_info_bxt.inl +++ b/opencl/source/gen9/hw_info_bxt.inl @@ -74,7 +74,8 @@ const RuntimeCapabilityTable BXT::capabilityTable{ false, // supportsDeviceEnqueue false, // supportsPipes false, // supportsOcl21Features - true // hostPtrTrackingEnabled + true, // hostPtrTrackingEnabled + false // levelZeroSupported }; WorkaroundTable BXT::workaroundTable = {}; diff --git a/opencl/source/gen9/hw_info_cfl.inl b/opencl/source/gen9/hw_info_cfl.inl index d9bcca0546..303f8cc826 100644 --- a/opencl/source/gen9/hw_info_cfl.inl +++ b/opencl/source/gen9/hw_info_cfl.inl @@ -69,7 +69,8 @@ const RuntimeCapabilityTable CFL::capabilityTable{ true, // supportsDeviceEnqueue true, // supportsPipes true, // supportsOcl21Features - true // hostPtrTrackingEnabled + true, // hostPtrTrackingEnabled + true // levelZeroSupported }; WorkaroundTable CFL::workaroundTable = {}; diff --git a/opencl/source/gen9/hw_info_glk.inl b/opencl/source/gen9/hw_info_glk.inl index 24b72fada9..4739145301 100644 --- a/opencl/source/gen9/hw_info_glk.inl +++ b/opencl/source/gen9/hw_info_glk.inl @@ -69,7 +69,8 @@ const RuntimeCapabilityTable GLK::capabilityTable{ false, // supportsDeviceEnqueue false, // supportsPipes false, // supportsOcl21Features - true // hostPtrTrackingEnabled + true, // hostPtrTrackingEnabled + false // levelZeroSupported }; WorkaroundTable GLK::workaroundTable = {}; diff --git a/opencl/source/gen9/hw_info_kbl.inl b/opencl/source/gen9/hw_info_kbl.inl index 662049521d..cb120cdd17 100644 --- a/opencl/source/gen9/hw_info_kbl.inl +++ b/opencl/source/gen9/hw_info_kbl.inl @@ -69,7 +69,8 @@ const RuntimeCapabilityTable KBL::capabilityTable{ true, // supportsDeviceEnqueue true, // supportsPipes true, // supportsOcl21Features - true // hostPtrTrackingEnabled + true, // hostPtrTrackingEnabled + true // levelZeroSupported }; WorkaroundTable KBL::workaroundTable = {}; diff --git a/opencl/source/gen9/hw_info_skl.inl b/opencl/source/gen9/hw_info_skl.inl index a25a9973ef..e2d5f9f282 100644 --- a/opencl/source/gen9/hw_info_skl.inl +++ b/opencl/source/gen9/hw_info_skl.inl @@ -77,7 +77,8 @@ const RuntimeCapabilityTable SKL::capabilityTable{ true, // supportsDeviceEnqueue true, // supportsPipes true, // supportsOcl21Features - true // hostPtrTrackingEnabled + true, // hostPtrTrackingEnabled + true // levelZeroSupported }; WorkaroundTable SKL::workaroundTable = {}; FeatureTable SKL::featureTable = {}; diff --git a/shared/source/helpers/hw_info.h b/shared/source/helpers/hw_info.h index 0d27a5a08b..4895c3f87e 100644 --- a/shared/source/helpers/hw_info.h +++ b/shared/source/helpers/hw_info.h @@ -57,6 +57,7 @@ struct RuntimeCapabilityTable { bool supportsPipes; bool supportsOcl21Features; bool hostPtrTrackingEnabled; + bool levelZeroSupported; }; struct HardwareCapabilities {