Skip to content

Commit 571007c

Browse files
Support low priority command queues
Related-to: LOCI-1124 Signed-off-by: Young Jin Yoon <young.jin.yoon@intel.com>
1 parent 5440c83 commit 571007c

File tree

5 files changed

+114
-3
lines changed

5 files changed

+114
-3
lines changed

level_zero/core/source/device/device.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ struct Device : _ze_device_handle_t {
122122
virtual void setSysmanHandle(SysmanDevice *pSysmanDevice) = 0;
123123
virtual SysmanDevice *getSysmanHandle() = 0;
124124
virtual ze_result_t getCsrForOrdinalAndIndex(NEO::CommandStreamReceiver **csr, uint32_t ordinal, uint32_t index) = 0;
125+
virtual ze_result_t getCsrForLowPriority(NEO::CommandStreamReceiver **csr) = 0;
125126
virtual ze_result_t mapOrdinalForAvailableEngineGroup(uint32_t *ordinal) = 0;
126127
};
127128

level_zero/core/source/device/device_imp.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,13 @@ ze_result_t DeviceImp::createCommandQueue(const ze_command_queue_desc_t *desc,
110110
NEO::CommandStreamReceiver *csr = nullptr;
111111
uint32_t engineGroupIndex = desc->ordinal;
112112
mapOrdinalForAvailableEngineGroup(&engineGroupIndex);
113-
auto ret = getCsrForOrdinalAndIndex(&csr, desc->ordinal, desc->index);
114-
if (ret != ZE_RESULT_SUCCESS) {
115-
return ret;
113+
if (desc->priority == ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW) {
114+
getCsrForLowPriority(&csr);
115+
} else {
116+
auto ret = getCsrForOrdinalAndIndex(&csr, desc->ordinal, desc->index);
117+
if (ret != ZE_RESULT_SUCCESS) {
118+
return ret;
119+
}
116120
}
117121

118122
UNRECOVERABLE_IF(csr == nullptr);
@@ -775,6 +779,27 @@ ze_result_t DeviceImp::getCsrForOrdinalAndIndex(NEO::CommandStreamReceiver **csr
775779
}
776780
return ZE_RESULT_SUCCESS;
777781
}
782+
783+
ze_result_t DeviceImp::getCsrForLowPriority(NEO::CommandStreamReceiver **csr) {
784+
if (this->getNEODevice()->getNumAvailableDevices() > 1) {
785+
for (auto &it : neoDevice->getDeviceById(0)->getEngines()) {
786+
if (it.osContext->isLowPriority()) {
787+
*csr = it.commandStreamReceiver;
788+
return ZE_RESULT_SUCCESS;
789+
}
790+
}
791+
} else {
792+
for (auto &it : neoDevice->getEngines()) {
793+
if (it.osContext->isLowPriority()) {
794+
*csr = it.commandStreamReceiver;
795+
return ZE_RESULT_SUCCESS;
796+
}
797+
}
798+
}
799+
// if the code falls through, we have no low priority context created by neoDevice.
800+
UNRECOVERABLE_IF(true);
801+
}
802+
778803
ze_result_t DeviceImp::mapOrdinalForAvailableEngineGroup(uint32_t *ordinal) {
779804
NEO::Device *neoDevice = this->neoDevice;
780805
if (this->getNEODevice()->getNumAvailableDevices() > 1) {

level_zero/core/source/device/device_imp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ struct DeviceImp : public Device {
7474
void setSysmanHandle(SysmanDevice *pSysman) override;
7575
SysmanDevice *getSysmanHandle() override;
7676
ze_result_t getCsrForOrdinalAndIndex(NEO::CommandStreamReceiver **csr, uint32_t ordinal, uint32_t index) override;
77+
ze_result_t getCsrForLowPriority(NEO::CommandStreamReceiver **csr) override;
7778
ze_result_t mapOrdinalForAvailableEngineGroup(uint32_t *ordinal) override;
7879

7980
NEO::Device *neoDevice = nullptr;

level_zero/core/test/unit_tests/mocks/mock_device.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,10 @@ struct Mock<Device> : public Device {
235235
return ZE_RESULT_SUCCESS;
236236
}
237237

238+
ze_result_t getCsrForLowPriority(NEO::CommandStreamReceiver **csr) override {
239+
return ZE_RESULT_SUCCESS;
240+
}
241+
238242
ze_result_t mapOrdinalForAvailableEngineGroup(uint32_t *ordinal) override {
239243
return ZE_RESULT_SUCCESS;
240244
}

level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,86 @@ HWTEST_F(CommandQueueIndirectAllocations, givenCommandQueueWhenExecutingCommandL
504504
commandQueue->destroy();
505505
}
506506

507+
using DeviceCreateCommandQueueTest = Test<DeviceFixture>;
508+
TEST_F(DeviceCreateCommandQueueTest, givenLowPriorityDescWhenCreateCommandQueueIsCalledThenLowPriorityCsrIsAssigned) {
509+
ze_command_queue_desc_t desc{};
510+
desc.ordinal = 0u;
511+
desc.index = 0u;
512+
desc.priority = ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW;
513+
514+
ze_command_queue_handle_t commandQueueHandle = {};
515+
516+
ze_result_t res = device->createCommandQueue(&desc, &commandQueueHandle);
517+
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
518+
auto commandQueue = static_cast<CommandQueueImp *>(L0::CommandQueue::fromHandle(commandQueueHandle));
519+
EXPECT_NE(commandQueue, nullptr);
520+
EXPECT_TRUE(commandQueue->getCsr()->getOsContext().isLowPriority());
521+
NEO::CommandStreamReceiver *csr = nullptr;
522+
device->getCsrForLowPriority(&csr);
523+
EXPECT_EQ(commandQueue->getCsr(), csr);
524+
commandQueue->destroy();
525+
}
526+
527+
TEST_F(DeviceCreateCommandQueueTest, givenNormalPriorityDescWhenCreateCommandQueueIsCalledWithValidArgumentThenCsrIsAssignedWithOrdinalAndIndex) {
528+
ze_command_queue_desc_t desc{};
529+
desc.ordinal = 0u;
530+
desc.index = 0u;
531+
desc.priority = ZE_COMMAND_QUEUE_PRIORITY_NORMAL;
532+
533+
ze_command_queue_handle_t commandQueueHandle = {};
534+
535+
ze_result_t res = device->createCommandQueue(&desc, &commandQueueHandle);
536+
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
537+
auto commandQueue = static_cast<CommandQueueImp *>(L0::CommandQueue::fromHandle(commandQueueHandle));
538+
EXPECT_NE(commandQueue, nullptr);
539+
EXPECT_FALSE(commandQueue->getCsr()->getOsContext().isLowPriority());
540+
NEO::CommandStreamReceiver *csr = nullptr;
541+
device->getCsrForOrdinalAndIndex(&csr, 0u, 0u);
542+
EXPECT_EQ(commandQueue->getCsr(), csr);
543+
commandQueue->destroy();
544+
}
545+
546+
TEST_F(DeviceCreateCommandQueueTest, givenLowPriorityDescAndWithoutLowPriorityCsrWhenCreateCommandQueueIsCalledThenAbortIsThrown) {
547+
// remove low priority EngineControl objects for negative testing
548+
neoDevice->engines.erase(std::remove_if(
549+
neoDevice->engines.begin(),
550+
neoDevice->engines.end(),
551+
[](EngineControl &p) { return p.osContext->isLowPriority(); }));
552+
553+
ze_command_queue_desc_t desc{};
554+
desc.ordinal = 0u;
555+
desc.index = 0u;
556+
desc.priority = ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW;
557+
558+
ze_command_queue_handle_t commandQueueHandle = {};
559+
560+
ze_result_t res{};
561+
EXPECT_THROW(res = device->createCommandQueue(&desc, &commandQueueHandle), std::exception);
562+
}
563+
564+
using MultiDeviceCreateCommandQueueTest = Test<MultiDeviceFixture>;
565+
566+
TEST_F(MultiDeviceCreateCommandQueueTest, givenLowPriorityDescWhenCreateCommandQueueIsCalledThenLowPriorityCsrIsAssigned) {
567+
auto device = driverHandle->devices[0];
568+
569+
ze_command_queue_desc_t desc{};
570+
desc.ordinal = 0u;
571+
desc.index = 0u;
572+
desc.priority = ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW;
573+
574+
ze_command_queue_handle_t commandQueueHandle = {};
575+
576+
ze_result_t res = device->createCommandQueue(&desc, &commandQueueHandle);
577+
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
578+
auto commandQueue = static_cast<CommandQueueImp *>(L0::CommandQueue::fromHandle(commandQueueHandle));
579+
EXPECT_NE(commandQueue, nullptr);
580+
EXPECT_TRUE(commandQueue->getCsr()->getOsContext().isLowPriority());
581+
NEO::CommandStreamReceiver *csr = nullptr;
582+
device->getCsrForLowPriority(&csr);
583+
EXPECT_EQ(commandQueue->getCsr(), csr);
584+
commandQueue->destroy();
585+
}
586+
507587
using ContextCreateCommandQueueTest = Test<ContextFixture>;
508588

509589
TEST_F(ContextCreateCommandQueueTest, givenCallToContextCreateCommandQueueThenCallSucceeds) {

0 commit comments

Comments
 (0)