OpenCL Queue Families extension 1/n

Basic implementation, some things will be tweaked in future commits

Related-To: NEO-5120
Signed-off-by: Maciej Dziuban <maciej.dziuban@intel.com>
This commit is contained in:
Maciej Dziuban
2020-11-16 11:43:03 +00:00
committed by Compute-Runtime-Automation
parent 2be1b36422
commit 14f92cc7a1
16 changed files with 621 additions and 109 deletions

View File

@@ -482,6 +482,74 @@ TEST_F(clCreateCommandQueueWithPropertiesApi, GivenDeviceQueueCreatedWithVarious
}
}
TEST_F(clCreateCommandQueueWithPropertiesApi, givenQueueFamilySelectedAndNotIndexWhenCreatingQueueThenFail) {
cl_queue_properties queueProperties[] = {
CL_QUEUE_FAMILY_INTEL,
0,
0,
};
auto queue = clCreateCommandQueueWithProperties(pContext, testedClDevice, queueProperties, &retVal);
EXPECT_EQ(nullptr, queue);
EXPECT_EQ(CL_INVALID_QUEUE_PROPERTIES, retVal);
}
TEST_F(clCreateCommandQueueWithPropertiesApi, givenQueueIndexSelectedAndNotFamilyWhenCreatingQueueThenFail) {
cl_queue_properties queueProperties[] = {
CL_QUEUE_INDEX_INTEL,
0,
0,
};
auto queue = clCreateCommandQueueWithProperties(pContext, testedClDevice, queueProperties, &retVal);
EXPECT_EQ(nullptr, queue);
EXPECT_EQ(CL_INVALID_QUEUE_PROPERTIES, retVal);
}
TEST_F(clCreateCommandQueueWithPropertiesApi, givenValidFamilyAndIndexSelectedWhenCreatingQueueThenReturnSuccess) {
cl_queue_properties queueProperties[] = {
CL_QUEUE_FAMILY_INTEL,
0,
CL_QUEUE_INDEX_INTEL,
0,
0,
};
auto queue = clCreateCommandQueueWithProperties(pContext, testedClDevice, queueProperties, &retVal);
EXPECT_NE(nullptr, queue);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(CL_SUCCESS, clReleaseCommandQueue(queue));
}
TEST_F(clCreateCommandQueueWithPropertiesApi, givenInvalidQueueFamilySelectedWhenCreatingQueueThenFail) {
const auto &families = castToObject<ClDevice>(testedClDevice)->getDevice().getEngineGroups();
cl_queue_properties queueProperties[] = {
CL_QUEUE_FAMILY_INTEL,
families.size(),
CL_QUEUE_INDEX_INTEL,
0,
0,
};
auto queue = clCreateCommandQueueWithProperties(pContext, testedClDevice, queueProperties, &retVal);
EXPECT_EQ(nullptr, queue);
EXPECT_EQ(CL_INVALID_QUEUE_PROPERTIES, retVal);
}
TEST_F(clCreateCommandQueueWithPropertiesApi, givenInvalidQueueIndexSelectedWhenCreatingQueueThenFail) {
cl_queue_properties queueProperties[] = {
CL_QUEUE_FAMILY_INTEL,
0,
CL_QUEUE_INDEX_INTEL,
50,
0,
};
auto queue = clCreateCommandQueueWithProperties(pContext, testedClDevice, queueProperties, &retVal);
EXPECT_EQ(nullptr, queue);
EXPECT_EQ(CL_INVALID_QUEUE_PROPERTIES, retVal);
}
using LowPriorityCommandQueueTest = ::testing::Test;
HWTEST_F(LowPriorityCommandQueueTest, GivenDeviceWithSubdevicesWhenCreatingLowPriorityCommandQueueThenEngineFromFirstSubdeviceIsTaken) {
DebugManagerStateRestore restorer;

View File

@@ -26,6 +26,7 @@
#include "opencl/test/unit_test/fixtures/dispatch_flags_fixture.h"
#include "opencl/test/unit_test/fixtures/image_fixture.h"
#include "opencl/test/unit_test/fixtures/memory_management_fixture.h"
#include "opencl/test/unit_test/helpers/raii_hw_helper.h"
#include "opencl/test/unit_test/helpers/unit_test_helper.h"
#include "opencl/test/unit_test/libult/ult_command_stream_receiver.h"
#include "opencl/test/unit_test/mocks/mock_allocation_properties.h"
@@ -35,6 +36,7 @@
#include "opencl/test/unit_test/mocks/mock_kernel.h"
#include "opencl/test/unit_test/mocks/mock_mdi.h"
#include "opencl/test/unit_test/mocks/mock_memory_manager.h"
#include "opencl/test/unit_test/mocks/mock_os_context.h"
#include "opencl/test/unit_test/mocks/mock_program.h"
#include "test.h"
@@ -1273,3 +1275,128 @@ HWTEST_F(KernelExecutionTypesTests, givenConcurrentKernelWhileDoingBlockedEnqueu
EXPECT_EQ(mockCsr.lastKernelExecutionType, KernelExecutionType::Concurrent);
mockCmdQ->isQueueBlocked();
}
struct CommandQueueOnSpecificEngineTests : ::testing::Test {
static void fillProperties(cl_queue_properties *properties, cl_uint queueFamily, cl_uint queueIndex) {
properties[0] = CL_QUEUE_FAMILY_INTEL;
properties[1] = queueFamily;
properties[2] = CL_QUEUE_INDEX_INTEL;
properties[3] = queueIndex;
properties[4] = 0;
}
template <typename GfxFamily, int ccsCount, int bcsCount>
class MockHwHelper : public HwHelperHw<GfxFamily> {
public:
const HwHelper::EngineInstancesContainer getGpgpuEngineInstances(const HardwareInfo &hwInfo) const override {
HwHelper::EngineInstancesContainer result{};
for (int i = 0; i < ccsCount; i++) {
result.push_back({aub_stream::ENGINE_CCS, EngineUsage::Regular});
}
for (int i = 0; i < bcsCount; i++) {
result.push_back({aub_stream::ENGINE_BCS, EngineUsage::Regular});
}
return result;
}
void addEngineToEngineGroup(std::vector<std::vector<EngineControl>> &engineGroups,
EngineControl &engine, const HardwareInfo &hwInfo) const override {
switch (engine.getEngineType()) {
case aub_stream::ENGINE_CCS:
engineGroups[static_cast<int>(EngineGroupType::Compute)].push_back(engine);
break;
case aub_stream::ENGINE_BCS:
engineGroups[static_cast<int>(EngineGroupType::Copy)].push_back(engine);
break;
default:
break;
}
}
};
template <typename GfxFamily, typename HwHelperType>
auto overrideHwHelper() {
return RAIIHwHelperFactory<HwHelperType>{::defaultHwInfo->platform.eRenderCoreFamily};
}
};
HWTEST_F(CommandQueueOnSpecificEngineTests, givenMultipleFamiliesWhenCreatingQueueOnSpecificEngineThenUseCorrectEngine) {
auto raiiHwHelper = overrideHwHelper<FamilyType, MockHwHelper<FamilyType, 1, 1>>();
MockContext context{};
cl_command_queue_properties properties[5] = {};
fillProperties(properties, 0, 0);
EngineControl &engineCcs = context.getDevice(0)->getEngine(aub_stream::ENGINE_CCS, false, false);
MockCommandQueue queueRcs(&context, context.getDevice(0), properties);
EXPECT_EQ(&engineCcs, &queueRcs.getGpgpuEngine());
EXPECT_FALSE(queueRcs.isCopyOnly);
fillProperties(properties, 1, 0);
EngineControl &engineBcs = context.getDevice(0)->getEngine(aub_stream::ENGINE_BCS, false, false);
MockCommandQueue queueBcs(&context, context.getDevice(0), properties);
EXPECT_EQ(engineBcs.commandStreamReceiver, queueBcs.getBcsCommandStreamReceiver());
EXPECT_TRUE(queueBcs.isCopyOnly);
EXPECT_NE(nullptr, queueBcs.getTimestampPacketContainer());
}
HWTEST_F(CommandQueueOnSpecificEngineTests, givenRootDeviceAndMultipleFamiliesWhenCreatingQueueOnSpecificEngineThenUseDefaultEngine) {
auto raiiHwHelper = overrideHwHelper<FamilyType, MockHwHelper<FamilyType, 1, 1>>();
UltClDeviceFactory deviceFactory{1, 2};
MockContext context{deviceFactory.rootDevices[0]};
cl_command_queue_properties properties[5] = {};
fillProperties(properties, 0, 0);
EngineControl &defaultEngine = context.getDevice(0)->getDefaultEngine();
MockCommandQueue defaultQueue(&context, context.getDevice(0), properties);
EXPECT_EQ(&defaultEngine, &defaultQueue.getGpgpuEngine());
EXPECT_FALSE(defaultQueue.isCopyOnly);
}
HWTEST_F(CommandQueueOnSpecificEngineTests, givenSubDeviceAndMultipleFamiliesWhenCreatingQueueOnSpecificEngineThenUseDefaultEngine) {
auto raiiHwHelper = overrideHwHelper<FamilyType, MockHwHelper<FamilyType, 1, 1>>();
UltClDeviceFactory deviceFactory{1, 2};
MockContext context{deviceFactory.subDevices[0]};
cl_command_queue_properties properties[5] = {};
fillProperties(properties, 0, 0);
EngineControl &engineCcs = context.getDevice(0)->getEngine(aub_stream::ENGINE_CCS, false, false);
MockCommandQueue queueRcs(&context, context.getDevice(0), properties);
EXPECT_EQ(&engineCcs, &queueRcs.getGpgpuEngine());
EXPECT_FALSE(queueRcs.isCopyOnly);
fillProperties(properties, 1, 0);
EngineControl &engineBcs = context.getDevice(0)->getEngine(aub_stream::ENGINE_BCS, false, false);
MockCommandQueue queueBcs(&context, context.getDevice(0), properties);
EXPECT_EQ(engineBcs.commandStreamReceiver, queueBcs.getBcsCommandStreamReceiver());
EXPECT_TRUE(queueBcs.isCopyOnly);
EXPECT_NE(nullptr, queueBcs.getTimestampPacketContainer());
}
HWTEST_F(CommandQueueOnSpecificEngineTests, givenBcsFamilySelectedWhenCreatingQueueOnSpecificEngineThenInitializeBcsProperly) {
auto raiiHwHelper = overrideHwHelper<FamilyType, MockHwHelper<FamilyType, 0, 1>>();
MockContext context{};
cl_command_queue_properties properties[5] = {};
fillProperties(properties, 0, 0);
EngineControl &engineBcs = context.getDevice(0)->getEngine(aub_stream::ENGINE_BCS, false, false);
MockCommandQueue queueBcs(&context, context.getDevice(0), properties);
EXPECT_EQ(engineBcs.commandStreamReceiver, queueBcs.getBcsCommandStreamReceiver());
EXPECT_TRUE(queueBcs.isCopyOnly);
EXPECT_NE(nullptr, queueBcs.getTimestampPacketContainer());
}
HWTEST_F(CommandQueueOnSpecificEngineTests, givenBliterDisabledAndBcsFamilySelectedWhenCreatingQueueOnSpecificEngineThenInitializeBcsProperly) {
DebugManagerStateRestore restore{};
DebugManager.flags.EnableBlitterOperationsSupport.set(0);
auto raiiHwHelper = overrideHwHelper<FamilyType, MockHwHelper<FamilyType, 0, 1>>();
MockContext context{};
cl_command_queue_properties properties[5] = {};
fillProperties(properties, 0, 0);
EngineControl &engineBcs = context.getDevice(0)->getEngine(aub_stream::ENGINE_BCS, false, false);
MockCommandQueue queueBcs(&context, context.getDevice(0), properties);
EXPECT_EQ(engineBcs.commandStreamReceiver, queueBcs.getBcsCommandStreamReceiver());
EXPECT_TRUE(queueBcs.isCopyOnly);
EXPECT_NE(nullptr, queueBcs.getTimestampPacketContainer());
}

View File

@@ -431,3 +431,38 @@ TEST(DeviceGenEngineTest, givenCreatedDeviceWhenRetrievingDefaultEngineThenOsCon
auto &defaultEngine = device->getDefaultEngine();
EXPECT_TRUE(defaultEngine.osContext->isDefaultContext());
}
TEST(DeviceGenEngineTest, givenNoEmptyGroupsWhenGettingNonEmptyGroupsThenReturnCorrectResults) {
const auto nonEmptyEngineGroup = std::vector<EngineControl>{EngineControl{nullptr, nullptr}};
auto device = std::unique_ptr<Device>(MockDevice::createWithNewExecutionEnvironment<Device>(nullptr));
auto &engineGroups = device->getEngineGroups();
engineGroups.clear();
engineGroups.push_back(nonEmptyEngineGroup);
engineGroups.push_back(nonEmptyEngineGroup);
engineGroups.push_back(nonEmptyEngineGroup);
engineGroups.push_back(nonEmptyEngineGroup);
EXPECT_EQ(&engineGroups[0], device->getNonEmptyEngineGroup(0));
EXPECT_EQ(&engineGroups[1], device->getNonEmptyEngineGroup(1));
EXPECT_EQ(&engineGroups[2], device->getNonEmptyEngineGroup(2));
EXPECT_EQ(&engineGroups[3], device->getNonEmptyEngineGroup(3));
EXPECT_EQ(nullptr, device->getNonEmptyEngineGroup(4));
}
TEST(DeviceGenEngineTest, givenEmptyGroupsWhenGettingNonEmptyGroupsThenReturnCorrectResults) {
const auto emptyEngineGroup = std::vector<EngineControl>{};
const auto nonEmptyEngineGroup = std::vector<EngineControl>{EngineControl{nullptr, nullptr}};
auto device = std::unique_ptr<Device>(MockDevice::createWithNewExecutionEnvironment<Device>(nullptr));
auto &engineGroups = device->getEngineGroups();
engineGroups.clear();
engineGroups.push_back(emptyEngineGroup);
engineGroups.push_back(nonEmptyEngineGroup);
engineGroups.push_back(emptyEngineGroup);
engineGroups.push_back(nonEmptyEngineGroup);
EXPECT_EQ(&engineGroups[1], device->getNonEmptyEngineGroup(0));
EXPECT_EQ(&engineGroups[3], device->getNonEmptyEngineGroup(1));
EXPECT_EQ(nullptr, device->getNonEmptyEngineGroup(2));
}

View File

@@ -6,10 +6,13 @@
*/
#include "shared/source/helpers/get_info.h"
#include "shared/test/unit_test/helpers/debug_manager_state_restore.h"
#include "opencl/source/cl_device/cl_device_info_map.h"
#include "opencl/test/unit_test/fixtures/cl_device_fixture.h"
#include "opencl/test/unit_test/fixtures/device_info_fixture.h"
#include "opencl/test/unit_test/helpers/raii_hw_helper.h"
#include "opencl/test/unit_test/mocks/mock_os_context.h"
#include "opencl/test/unit_test/mocks/ult_cl_device_factory.h"
#include "test.h"
@@ -677,6 +680,111 @@ TEST(GetDeviceInfo, WhenQueryingGenericAddressSpaceSupportThenProperValueIsRetur
EXPECT_EQ(expectedGenericAddressSpaceSupport, genericAddressSpaceSupport);
}
template <typename GfxFamily, int ccsCount, int bcsCount>
class MockHwHelper : public HwHelperHw<GfxFamily> {
public:
const HwHelper::EngineInstancesContainer getGpgpuEngineInstances(const HardwareInfo &hwInfo) const override {
HwHelper::EngineInstancesContainer result{};
for (int i = 0; i < ccsCount; i++) {
result.push_back({aub_stream::ENGINE_CCS, EngineUsage::Regular});
}
for (int i = 0; i < bcsCount; i++) {
result.push_back({aub_stream::ENGINE_BCS, EngineUsage::Regular});
}
return result;
}
void addEngineToEngineGroup(std::vector<std::vector<EngineControl>> &engineGroups,
EngineControl &engine, const HardwareInfo &hwInfo) const override {
switch (engine.getEngineType()) {
case aub_stream::ENGINE_CCS:
engineGroups[static_cast<int>(EngineGroupType::Compute)].push_back(engine);
break;
case aub_stream::ENGINE_BCS:
engineGroups[static_cast<int>(EngineGroupType::Copy)].push_back(engine);
break;
default:
break;
}
}
static auto overrideHwHelper() {
return RAIIHwHelperFactory<MockHwHelper<GfxFamily, ccsCount, bcsCount>>{::defaultHwInfo->platform.eRenderCoreFamily};
}
};
using GetDeviceInfoQueueFamilyTest = ::testing::Test;
HWTEST_F(GetDeviceInfoQueueFamilyTest, givenSingleDeviceWhenInitializingCapsThenReturnCorrectFamilies) {
auto raiiHwHelper = MockHwHelper<FamilyType, 3, 1>::overrideHwHelper();
UltClDeviceFactory deviceFactory{1, 0};
ClDevice &clDevice = *deviceFactory.rootDevices[0];
size_t paramRetSize{};
cl_uint numQueueFamilies{};
auto retVal = clDevice.getDeviceInfo(CL_DEVICE_NUM_QUEUE_FAMILIES_INTEL, sizeof(numQueueFamilies), &numQueueFamilies, &paramRetSize);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(2u, numQueueFamilies);
cl_queue_family_properties_intel families[static_cast<int>(EngineGroupType::MaxEngineGroups)];
retVal = clDevice.getDeviceInfo(CL_DEVICE_QUEUE_FAMILY_PROPERTIES_INTEL, sizeof(families), families, &paramRetSize);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(2u, paramRetSize / sizeof(cl_queue_family_properties_intel));
EXPECT_EQ(CL_QUEUE_CAPABILITY_ALL_INTEL, families[0].capabilities);
EXPECT_EQ(3u, families[0].count);
EXPECT_EQ(clDevice.getDeviceInfo().queueOnHostProperties, families[0].properties);
EXPECT_EQ(CL_QUEUE_CAPABILITY_ALL_INTEL, families[1].capabilities);
EXPECT_EQ(1u, families[1].count);
EXPECT_EQ(clDevice.getDeviceInfo().queueOnHostProperties, families[1].properties);
}
HWTEST_F(GetDeviceInfoQueueFamilyTest, givenSubDeviceWhenInitializingCapsThenReturnCorrectFamilies) {
auto raiiHwHelper = MockHwHelper<FamilyType, 3, 1>::overrideHwHelper();
UltClDeviceFactory deviceFactory{1, 2};
ClDevice &clDevice = *deviceFactory.subDevices[1];
size_t paramRetSize{};
cl_uint numQueueFamilies{};
auto retVal = clDevice.getDeviceInfo(CL_DEVICE_NUM_QUEUE_FAMILIES_INTEL, sizeof(numQueueFamilies), &numQueueFamilies, &paramRetSize);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(2u, numQueueFamilies);
cl_queue_family_properties_intel families[static_cast<int>(EngineGroupType::MaxEngineGroups)];
retVal = clDevice.getDeviceInfo(CL_DEVICE_QUEUE_FAMILY_PROPERTIES_INTEL, sizeof(families), families, &paramRetSize);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(2u, paramRetSize / sizeof(cl_queue_family_properties_intel));
EXPECT_EQ(CL_QUEUE_CAPABILITY_ALL_INTEL, families[0].capabilities);
EXPECT_EQ(3u, families[0].count);
EXPECT_EQ(clDevice.getDeviceInfo().queueOnHostProperties, families[0].properties);
EXPECT_EQ(CL_QUEUE_CAPABILITY_ALL_INTEL, families[1].capabilities);
EXPECT_EQ(1u, families[1].count);
EXPECT_EQ(clDevice.getDeviceInfo().queueOnHostProperties, families[1].properties);
}
HWTEST_F(GetDeviceInfoQueueFamilyTest, givenDeviceRootDeviceWhenInitializingCapsThenReturnDefaultFamily) {
UltClDeviceFactory deviceFactory{1, 2};
ClDevice &clDevice = *deviceFactory.rootDevices[0];
size_t paramRetSize{};
cl_uint numQueueFamilies{};
auto retVal = clDevice.getDeviceInfo(CL_DEVICE_NUM_QUEUE_FAMILIES_INTEL, sizeof(numQueueFamilies), &numQueueFamilies, &paramRetSize);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(1u, numQueueFamilies);
cl_queue_family_properties_intel families[static_cast<int>(EngineGroupType::MaxEngineGroups)];
retVal = clDevice.getDeviceInfo(CL_DEVICE_QUEUE_FAMILY_PROPERTIES_INTEL, sizeof(families), families, &paramRetSize);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(1u, paramRetSize / sizeof(cl_queue_family_properties_intel));
EXPECT_EQ(CL_QUEUE_CAPABILITY_ALL_INTEL, families[0].capabilities);
EXPECT_EQ(1u, families[0].count);
EXPECT_EQ(clDevice.getDeviceInfo().queueOnHostProperties, families[0].properties);
}
struct GetDeviceInfo : public ::testing::TestWithParam<uint32_t /*cl_device_info*/> {
void SetUp() override {
param = GetParam();
@@ -769,6 +877,7 @@ cl_device_info deviceInfoParams[] = {
CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG,
CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT,
CL_DEVICE_NUMERIC_VERSION,
CL_DEVICE_NUM_QUEUE_FAMILIES_INTEL,
CL_DEVICE_OPENCL_C_ALL_VERSIONS,
CL_DEVICE_OPENCL_C_FEATURES,
CL_DEVICE_OPENCL_C_VERSION,
@@ -795,6 +904,7 @@ cl_device_info deviceInfoParams[] = {
CL_DEVICE_PRINTF_BUFFER_SIZE,
CL_DEVICE_PROFILE,
CL_DEVICE_PROFILING_TIMER_RESOLUTION,
CL_DEVICE_QUEUE_FAMILY_PROPERTIES_INTEL,
CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE,
CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE,
CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES,

View File

@@ -45,3 +45,25 @@ TEST(QueueHelpersTest, givenPropertyListWithPropertyOfValueZeroWhenGettingProper
}
}
}
TEST(QueueHelpersTest, givenPropertiesWhenGettingPropertyValuesThenReturnCorrectFoundPropertyValue) {
cl_queue_properties nonExistantProperty = 0xCC;
cl_queue_properties properties[] = {
0xAA,
3,
0xBB,
0,
0};
bool foundProperty = false;
EXPECT_EQ(properties[1], getCmdQueueProperties<cl_queue_properties>(properties, properties[0], &foundProperty));
EXPECT_TRUE(foundProperty);
foundProperty = false;
EXPECT_EQ(properties[3], getCmdQueueProperties<cl_queue_properties>(properties, properties[2], &foundProperty));
EXPECT_TRUE(foundProperty);
foundProperty = false;
EXPECT_EQ(0u, getCmdQueueProperties<cl_queue_properties>(properties, nonExistantProperty, &foundProperty));
EXPECT_FALSE(foundProperty);
}