diff --git a/opencl/source/api/api.cpp b/opencl/source/api/api.cpp index 669e5ee48a..d6586cd49a 100644 --- a/opencl/source/api/api.cpp +++ b/opencl/source/api/api.cpp @@ -107,15 +107,18 @@ cl_int CL_API_CALL clGetPlatformIDs(cl_uint numEntries, break; } } + cl_uint numPlatformsToExpose = std::min(numEntries, static_cast(platformsImpl.size())); + if (numEntries == 0) { + numPlatformsToExpose = static_cast(platformsImpl.size()); + } if (platforms) { - // we only have one platform so we can program that directly - platforms[0] = platformsImpl[0].get(); + for (auto i = 0u; i < numPlatformsToExpose; i++) { + platforms[i] = platformsImpl[i].get(); + } } - // we only have a single platform at this time, so return 1 if num_platforms - // is non-nullptr if (numPlatforms) { - *numPlatforms = 1; + *numPlatforms = numPlatformsToExpose; } } while (false); TRACING_EXIT(clGetPlatformIDs, &retVal); diff --git a/opencl/source/platform/platform.cpp b/opencl/source/platform/platform.cpp index f214e4ad19..afaac2152f 100644 --- a/opencl/source/platform/platform.cpp +++ b/opencl/source/platform/platform.cpp @@ -273,7 +273,9 @@ std::vector Platform::groupDevices(DeviceVector devices) { auto platformId = platformsMap[productFamily]; outDevices[platformId].push_back(std::move(device)); } - std::reverse(outDevices.begin(), outDevices.end()); + std::sort(outDevices.begin(), outDevices.end(), [](DeviceVector &lhs, DeviceVector &rhs) -> bool { + return lhs[0]->getHardwareInfo().platform.eProductFamily > rhs[0]->getHardwareInfo().platform.eProductFamily; + }); return outDevices; } diff --git a/opencl/test/unit_test/api/cl_get_platform_ids_tests.inl b/opencl/test/unit_test/api/cl_get_platform_ids_tests.inl index 5a11dfe6c2..b6cee7e163 100644 --- a/opencl/test/unit_test/api/cl_get_platform_ids_tests.inl +++ b/opencl/test/unit_test/api/cl_get_platform_ids_tests.inl @@ -5,6 +5,7 @@ * */ +#include "shared/source/device/root_device.h" #include "shared/source/os_interface/device_factory.h" #include "shared/test/unit_test/helpers/ult_hw_config.h" @@ -84,6 +85,50 @@ TEST(clGetPlatformIDsNegativeTests, whenFailToCreateDeviceThenClGetPlatfomsIdsRe platformsImpl.clear(); } + +TEST(clGetPlatformIDsMultiPlatformTest, whenCreateDevicesWithDifferentProductFamilyThenClGetPlatformIdsCreatesMultiplePlatformsProperlySorted) { + DebugManagerStateRestore restorer; + const size_t numRootDevices = 2u; + DebugManager.flags.CreateMultipleRootDevices.set(numRootDevices); + VariableBackup createFuncBackup{&DeviceFactory::createRootDeviceFunc}; + DeviceFactory::createRootDeviceFunc = [](ExecutionEnvironment &executionEnvironment, uint32_t rootDeviceIndex) -> std::unique_ptr { + auto device = std::unique_ptr(Device::create(&executionEnvironment, rootDeviceIndex)); + auto hwInfo = device->getRootDeviceEnvironment().getMutableHardwareInfo(); + if (rootDeviceIndex == 0) { + hwInfo->platform.eProductFamily = IGFX_SKYLAKE; + } else { + hwInfo->platform.eProductFamily = IGFX_KABYLAKE; + } + return device; + }; + platformsImpl.clear(); + + cl_int retVal = CL_SUCCESS; + cl_platform_id platformsRet[2]; + cl_uint numPlatforms = 0; + + retVal = clGetPlatformIDs(0, nullptr, &numPlatforms); + EXPECT_EQ(2u, numPlatforms); + EXPECT_EQ(CL_SUCCESS, retVal); + + numPlatforms = 0u; + retVal = clGetPlatformIDs(2u, platformsRet, &numPlatforms); + EXPECT_EQ(2u, numPlatforms); + EXPECT_EQ(CL_SUCCESS, retVal); + + EXPECT_NE(nullptr, platformsRet[0]); + auto platform0 = castToObject(platformsRet[0]); + EXPECT_EQ(1u, platform0->getNumDevices()); + EXPECT_EQ(IGFX_KABYLAKE, platform0->getClDevice(0)->getHardwareInfo().platform.eProductFamily); + EXPECT_EQ(1u, platform0->getClDevice(0)->getRootDeviceIndex()); + + EXPECT_NE(nullptr, platformsRet[1]); + auto platform1 = castToObject(platformsRet[1]); + EXPECT_EQ(1u, platform1->getNumDevices()); + EXPECT_EQ(IGFX_SKYLAKE, platform1->getClDevice(0)->getHardwareInfo().platform.eProductFamily); + EXPECT_EQ(0u, platform1->getClDevice(0)->getRootDeviceIndex()); + platformsImpl.clear(); +} TEST(clGetPlatformIDsNegativeTests, whenFailToCreatePlatformThenClGetPlatfomsIdsReturnsOutOfHostMemoryError) { VariableBackup createFuncBackup{&Platform::createFunc}; Platform::createFunc = [](ExecutionEnvironment &executionEnvironment) -> std::unique_ptr { diff --git a/opencl/test/unit_test/platform/platform_tests.cpp b/opencl/test/unit_test/platform/platform_tests.cpp index d2e504e27a..6c7cddad5f 100644 --- a/opencl/test/unit_test/platform/platform_tests.cpp +++ b/opencl/test/unit_test/platform/platform_tests.cpp @@ -424,13 +424,6 @@ TEST(PlatformInitLoopTests, givenPlatformWithDebugSettingWhenInitIsCalledThenItE } TEST(PlatformGroupDevicesTest, whenMultipleDevicesAreCreatedThenGroupDevicesCreatesVectorPerEachProductFamily) { - struct MockRootDeviceEnvironment : RootDeviceEnvironment { - using RootDeviceEnvironment::RootDeviceEnvironment; - const HardwareInfo *getHardwareInfo() const override { - return &ownHardwareInfo; - } - HardwareInfo ownHardwareInfo = *platformDevices[0]; - }; DebugManagerStateRestore restorer; const size_t numRootDevices = 5u; @@ -444,16 +437,16 @@ TEST(PlatformGroupDevicesTest, whenMultipleDevicesAreCreatedThenGroupDevicesCrea EXPECT_EQ(numRootDevices, inputDevices.size()); auto skl0Device = inputDevices[0].get(); - auto skl1Device = inputDevices[1].get(); - auto skl2Device = inputDevices[2].get(); - auto kbl0Device = inputDevices[3].get(); + auto kbl0Device = inputDevices[1].get(); + auto skl1Device = inputDevices[2].get(); + auto skl2Device = inputDevices[3].get(); auto cfl0Device = inputDevices[4].get(); - static_cast(*executionEnvironment->rootDeviceEnvironments[0]).ownHardwareInfo.platform.eProductFamily = IGFX_SKYLAKE; - static_cast(*executionEnvironment->rootDeviceEnvironments[1]).ownHardwareInfo.platform.eProductFamily = IGFX_SKYLAKE; - static_cast(*executionEnvironment->rootDeviceEnvironments[2]).ownHardwareInfo.platform.eProductFamily = IGFX_SKYLAKE; - static_cast(*executionEnvironment->rootDeviceEnvironments[3]).ownHardwareInfo.platform.eProductFamily = IGFX_KABYLAKE; - static_cast(*executionEnvironment->rootDeviceEnvironments[4]).ownHardwareInfo.platform.eProductFamily = IGFX_COFFEELAKE; + executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo()->platform.eProductFamily = IGFX_SKYLAKE; + executionEnvironment->rootDeviceEnvironments[1]->getMutableHardwareInfo()->platform.eProductFamily = IGFX_KABYLAKE; + executionEnvironment->rootDeviceEnvironments[2]->getMutableHardwareInfo()->platform.eProductFamily = IGFX_SKYLAKE; + executionEnvironment->rootDeviceEnvironments[3]->getMutableHardwareInfo()->platform.eProductFamily = IGFX_SKYLAKE; + executionEnvironment->rootDeviceEnvironments[4]->getMutableHardwareInfo()->platform.eProductFamily = IGFX_COFFEELAKE; auto groupedDevices = Platform::groupDevices(std::move(inputDevices));