diff --git a/opencl/test/unit_test/device/sub_device_tests.cpp b/opencl/test/unit_test/device/sub_device_tests.cpp index 557b2107a2..d8eeda910e 100644 --- a/opencl/test/unit_test/device/sub_device_tests.cpp +++ b/opencl/test/unit_test/device/sub_device_tests.cpp @@ -360,7 +360,8 @@ struct EngineInstancedDeviceTests : public ::testing::Test { return (numCcs == expectedNumCcs); } - bool hasEngineInstancedEngines(MockSubDevice *device, aub_stream::EngineType engineType) { + template + bool hasEngineInstancedEngines(MockDeviceT *device, aub_stream::EngineType engineType) { bool ccsFound = false; for (auto &engine : device->engines) { @@ -585,10 +586,11 @@ TEST_F(EngineInstancedDeviceTests, givenAffinityMaskSetWhenCreatingDevicesThenFi } } -TEST_F(EngineInstancedDeviceTests, givenAffinityMaskForSingle3rdLevelDeviceWhenCreatingDevicesThenCreate2ndLevelAsGeneric) { +TEST_F(EngineInstancedDeviceTests, givenAffinityMaskForSingle3rdLevelDeviceWhenCreatingDevicesThenCreate2ndLevelAsEngineInstanced) { constexpr uint32_t genericDevicesCount = 2; constexpr uint32_t ccsCount = 2; - constexpr uint32_t create2ndLevelAsGeneric[2] = {false, true}; + constexpr uint32_t create2ndLevelAsEngineInstanced[2] = {false, true}; + constexpr uint32_t engineInstanced2ndLevelEngineIndex = 1; DebugManager.flags.ZE_AFFINITY_MASK.set("0.0, 0.1.1"); @@ -605,15 +607,22 @@ TEST_F(EngineInstancedDeviceTests, givenAffinityMaskForSingle3rdLevelDeviceWhenC EXPECT_FALSE(subDevice->engines[0].osContext->isRootDevice()); - EXPECT_FALSE(subDevice->engineInstanced); - EXPECT_EQ(aub_stream::EngineType::NUM_ENGINES, subDevice->engineInstancedType); + if (create2ndLevelAsEngineInstanced[i]) { + auto engineType = static_cast(aub_stream::EngineType::ENGINE_CCS + engineInstanced2ndLevelEngineIndex); + + DeviceBitfield deviceBitfield = (1llu << i); + EXPECT_TRUE(isEngineInstanced(subDevice, engineType, i, deviceBitfield)); + EXPECT_TRUE(hasEngineInstancedEngines(subDevice, engineType)); + + EXPECT_EQ(1u, subDevice->getNumAvailableDevices()); + + continue; + } EXPECT_TRUE(hasAllEngines(subDevice)); - if (create2ndLevelAsGeneric[i]) { - EXPECT_EQ(1u, subDevice->getNumAvailableDevices()); - continue; - } + EXPECT_FALSE(subDevice->engineInstanced); + EXPECT_EQ(aub_stream::EngineType::NUM_ENGINES, subDevice->engineInstancedType); EXPECT_EQ(ccsCount, subDevice->getNumAvailableDevices()); @@ -628,6 +637,34 @@ TEST_F(EngineInstancedDeviceTests, givenAffinityMaskForSingle3rdLevelDeviceWhenC } } +TEST_F(EngineInstancedDeviceTests, givenAffinityMaskForSingle3rdLevelDeviceOnlyWhenCreatingDevicesThenCreate1stLevelAsEngineInstanced) { + constexpr uint32_t genericDevicesCount = 2; + constexpr uint32_t ccsCount = 2; + constexpr uint32_t genericDeviceIndex = 1; + constexpr uint32_t engineInstancedEngineIndex = 1; + + DebugManager.flags.ZE_AFFINITY_MASK.set("0.1.1"); + + if (!createDevices(genericDevicesCount, ccsCount)) { + GTEST_SKIP(); + } + + EXPECT_FALSE(hasRootCsrOnly(rootDevice)); + + auto engineType = static_cast(aub_stream::EngineType::ENGINE_CCS + engineInstancedEngineIndex); + + DeviceBitfield deviceBitfield = (1llu << genericDeviceIndex); + + EXPECT_FALSE(rootDevice->engines[0].osContext->isRootDevice()); + EXPECT_TRUE(rootDevice->engineInstanced); + EXPECT_TRUE(rootDevice->getNumAvailableDevices() == 1); + EXPECT_TRUE(engineType == rootDevice->engineInstancedType); + EXPECT_TRUE(deviceBitfield == rootDevice->getDeviceBitfield()); + EXPECT_EQ(1u, rootDevice->getDeviceBitfield().count()); + + EXPECT_TRUE(hasEngineInstancedEngines(rootDevice, engineType)); +} + TEST(SubDevicesTest, whenInitializeRootCsrThenDirectSubmissionIsNotInitialized) { auto device = std::make_unique(); device->initializeRootCommandStreamReceiver(); diff --git a/shared/source/device/device.cpp b/shared/source/device/device.cpp index cf80dee93e..ea1aae5698 100644 --- a/shared/source/device/device.cpp +++ b/shared/source/device/device.cpp @@ -157,11 +157,42 @@ bool Device::createSubDevices() { return true; } +void Device::setAsEngineInstanced() { + if (subdevices.size() > 0) { + return; + } + + UNRECOVERABLE_IF(deviceBitfield.count() != 1); + + uint32_t subDeviceIndex = Math::log2(static_cast(deviceBitfield.to_ulong())); + auto enginesMask = getRootDeviceEnvironment().deviceAffinityMask.getEnginesMask(subDeviceIndex); + + if (enginesMask.count() != 1) { + return; + } + + auto ccsCount = getHardwareInfo().gtSystemInfo.CCSInfo.NumberOfCCSEnabled; + + for (uint32_t i = 0; i < ccsCount; i++) { + if (!enginesMask.test(i)) { + continue; + } + + UNRECOVERABLE_IF(engineInstanced); + engineInstanced = true; + engineInstancedType = static_cast(aub_stream::EngineType::ENGINE_CCS + i); + } + + UNRECOVERABLE_IF(!engineInstanced); +} + bool Device::createDeviceImpl() { if (!createSubDevices()) { return false; } + setAsEngineInstanced(); + auto &hwInfo = getHardwareInfo(); preemptionMode = PreemptionHelper::getDefaultPreemptionMode(hwInfo); diff --git a/shared/source/device/device.h b/shared/source/device/device.h index 62547d7af5..a4691a1fa1 100644 --- a/shared/source/device/device.h +++ b/shared/source/device/device.h @@ -142,6 +142,7 @@ class Device : public ReferenceTrackedObject { bool createEngineInstancedSubDevices(); virtual bool genericSubDevicesAllowed(); bool engineInstancedSubDevicesAllowed(); + void setAsEngineInstanced(); DeviceInfo deviceInfo = {}; diff --git a/shared/test/common/mocks/mock_device.h b/shared/test/common/mocks/mock_device.h index 26b3b587ab..46e4838857 100644 --- a/shared/test/common/mocks/mock_device.h +++ b/shared/test/common/mocks/mock_device.h @@ -53,6 +53,7 @@ class MockDevice : public RootDevice { using Device::createSubDevices; using Device::deviceInfo; using Device::engineGroups; + using Device::engineInstanced; using Device::engineInstancedType; using Device::engines; using Device::executionEnvironment;