diff --git a/level_zero/core/source/device/device_imp.cpp b/level_zero/core/source/device/device_imp.cpp index e9c715defa..2f423a90aa 100644 --- a/level_zero/core/source/device/device_imp.cpp +++ b/level_zero/core/source/device/device_imp.cpp @@ -117,7 +117,21 @@ ze_result_t DeviceImp::createCommandQueue(const ze_command_queue_desc_t *desc, auto &selectorCopyEngine = this->neoDevice->getDeviceById(0)->getSelectorCopyEngine(); csr = this->neoDevice->getDeviceById(0)->getEngine(NEO::EngineHelpers::getBcsEngineType(neoDevice->getHardwareInfo(), selectorCopyEngine), false).commandStreamReceiver; } else { - csr = neoDevice->getDefaultEngine().commandStreamReceiver; + const auto &hardwareInfo = this->neoDevice->getHardwareInfo(); + auto &hwHelper = NEO::HwHelper::get(hardwareInfo.platform.eRenderCoreFamily); + + if (desc->ordinal >= NEO::HwHelper::getEnginesCount(hardwareInfo)) { + return ZE_RESULT_ERROR_INVALID_ARGUMENT; + } + + if (desc->ordinal == 0) { + csr = neoDevice->getEngine(0).commandStreamReceiver; + } else { + // Skip low-priority and internal engines in engines vector + csr = neoDevice->getEngine(desc->ordinal + hwHelper.internalUsageEngineIndex).commandStreamReceiver; + } + + UNRECOVERABLE_IF(csr == nullptr); } *commandQueue = CommandQueue::create(productFamily, this, csr, desc, useBliter); diff --git a/level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue.cpp b/level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue.cpp index 72ac4b30ab..abc7af214e 100644 --- a/level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue.cpp +++ b/level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue.cpp @@ -49,6 +49,40 @@ TEST_F(CommandQueueCreate, whenCreatingCommandQueueThenItIsInitialized) { commandQueue->destroy(); } +TEST_F(CommandQueueCreate, givenOrdinalThenQueueIsCreatedOnlyIfOrdinalIsLessThanNumOfAsyncComputeEngines) { + ze_device_properties_t deviceProperties; + ze_result_t res = device->getProperties(&deviceProperties); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); + + ze_command_queue_desc_t desc = {}; + desc.version = ZE_COMMAND_QUEUE_DESC_VERSION_CURRENT; + desc.ordinal = deviceProperties.numAsyncComputeEngines; + + ze_command_queue_handle_t commandQueue = {}; + res = device->createCommandQueue(&desc, &commandQueue); + EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, res); + EXPECT_EQ(nullptr, commandQueue); + + desc.ordinal = 0; + res = device->createCommandQueue(&desc, &commandQueue); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); + EXPECT_NE(nullptr, commandQueue); + + L0::CommandQueue::fromHandle(commandQueue)->destroy(); + + const auto &hardwareInfo = neoDevice->getHardwareInfo(); + auto &hwHelper = NEO::HwHelper::get(hardwareInfo.platform.eRenderCoreFamily); + + for (uint32_t i = hwHelper.internalUsageEngineIndex; i < NEO::HwHelper::getEnginesCount(hardwareInfo); i++) { + desc.ordinal = i; + res = device->createCommandQueue(&desc, &commandQueue); + EXPECT_EQ(ZE_RESULT_SUCCESS, res); + EXPECT_NE(nullptr, commandQueue); + + L0::CommandQueue::fromHandle(commandQueue)->destroy(); + } +} + using CommandQueueSBASupport = IsWithinProducts; struct MockMemoryManagerCommandQueueSBA : public MemoryManagerMock { diff --git a/opencl/test/unit_test/device/device_tests.cpp b/opencl/test/unit_test/device/device_tests.cpp index 271a9af3cd..e9c791133f 100644 --- a/opencl/test/unit_test/device/device_tests.cpp +++ b/opencl/test/unit_test/device/device_tests.cpp @@ -54,7 +54,7 @@ TEST_F(DeviceTest, givenDeviceWhenEngineIsCreatedThenSetInitialValueForTag) { } } -TEST_F(DeviceTest, givenDeviceWhenAskedForSpecificEngineThenRetrunIt) { +TEST_F(DeviceTest, givenDeviceWhenAskedForSpecificEngineThenReturnIt) { auto &engines = HwHelper::get(defaultHwInfo->platform.eRenderCoreFamily).getGpgpuEngineInstances(*defaultHwInfo); for (uint32_t i = 0; i < engines.size(); i++) { bool lowPriority = (HwHelper::lowPriorityGpgpuEngineIndex == i); @@ -66,6 +66,14 @@ TEST_F(DeviceTest, givenDeviceWhenAskedForSpecificEngineThenRetrunIt) { EXPECT_THROW(pDevice->getEngine(aub_stream::ENGINE_VCS, false), std::exception); } +TEST_F(DeviceTest, givenDeviceWhenAskedForEngineWithValidIndexThenReturnIt) { + auto &engines = HwHelper::get(defaultHwInfo->platform.eRenderCoreFamily).getGpgpuEngineInstances(*defaultHwInfo); + for (uint32_t i = 0; i < engines.size(); i++) { + auto &deviceEngine = pDevice->getEngine(i); + EXPECT_EQ(deviceEngine.osContext->getEngineType(), engines[i]); + } +} + TEST_F(DeviceTest, givenDebugVariableToAlwaysChooseEngineZeroWhenNotExistingEngineSelectedThenIndexZeroEngineIsReturned) { DebugManagerStateRestore restore; DebugManager.flags.OverrideInvalidEngineWithDefault.set(true); diff --git a/shared/source/device/device.cpp b/shared/source/device/device.cpp index 137248951a..1037d3a77f 100644 --- a/shared/source/device/device.cpp +++ b/shared/source/device/device.cpp @@ -207,6 +207,11 @@ EngineControl &Device::getEngine(aub_stream::EngineType engineType, bool lowPrio UNRECOVERABLE_IF(true); } +EngineControl &Device::getEngine(uint32_t index) { + UNRECOVERABLE_IF(index >= engines.size()); + return engines[index]; +} + bool Device::getDeviceAndHostTimer(uint64_t *deviceTimestamp, uint64_t *hostTimestamp) const { TimeStampData queueTimeStamp; bool retVal = getOSTime()->getCpuGpuTime(&queueTimeStamp); diff --git a/shared/source/device/device.h b/shared/source/device/device.h index b816723756..289480b16d 100644 --- a/shared/source/device/device.h +++ b/shared/source/device/device.h @@ -42,6 +42,7 @@ class Device : public ReferenceTrackedObject { const HardwareInfo &getHardwareInfo() const; const DeviceInfo &getDeviceInfo() const; EngineControl &getEngine(aub_stream::EngineType engineType, bool lowPriority); + EngineControl &getEngine(uint32_t index); EngineControl &getDefaultEngine(); EngineControl &getInternalEngine(); std::atomic &getSelectorCopyEngine();