mirror of
https://github.com/intel/compute-runtime.git
synced 2025-09-10 12:53:42 +08:00
Use ZE_AFFINITY_MASK for neo devices
Resolves: NEO-5438 Signed-off-by: Lukasz Jobczyk <lukasz.jobczyk@intel.com>
This commit is contained in:

committed by
Compute-Runtime-Automation

parent
2eaf830aff
commit
8ed14d0c9f
@ -177,80 +177,17 @@ DriverHandleImp::~DriverHandleImp() {
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t DriverHandleImp::parseAffinityMask(std::vector<std::unique_ptr<NEO::Device>> &neoDevices) {
|
||||
std::vector<std::vector<bool>> affinityMaskBitSet(neoDevices.size());
|
||||
for (uint32_t i = 0; i < affinityMaskBitSet.size(); i++) {
|
||||
affinityMaskBitSet[i].resize(neoDevices[i]->getNumAvailableDevices());
|
||||
}
|
||||
|
||||
size_t pos = 0;
|
||||
while (pos < this->affinityMaskString.size()) {
|
||||
size_t posNextDot = this->affinityMaskString.find_first_of(".", pos);
|
||||
size_t posNextComma = this->affinityMaskString.find_first_of(",", pos);
|
||||
std::string rootDeviceString = this->affinityMaskString.substr(pos, std::min(posNextDot, posNextComma) - pos);
|
||||
uint32_t rootDeviceIndex = static_cast<uint32_t>(std::stoul(rootDeviceString, nullptr, 0));
|
||||
if (rootDeviceIndex < neoDevices.size()) {
|
||||
pos += rootDeviceString.size();
|
||||
if (posNextDot != std::string::npos &&
|
||||
this->affinityMaskString.at(pos) == '.' && posNextDot < posNextComma) {
|
||||
pos++;
|
||||
std::string subDeviceString = this->affinityMaskString.substr(pos, posNextComma - pos);
|
||||
uint32_t subDeviceIndex = static_cast<uint32_t>(std::stoul(subDeviceString, nullptr, 0));
|
||||
if (subDeviceIndex < neoDevices[rootDeviceIndex]->getNumAvailableDevices()) {
|
||||
affinityMaskBitSet[rootDeviceIndex][subDeviceIndex] = true;
|
||||
}
|
||||
} else {
|
||||
std::fill(affinityMaskBitSet[rootDeviceIndex].begin(),
|
||||
affinityMaskBitSet[rootDeviceIndex].end(),
|
||||
true);
|
||||
}
|
||||
}
|
||||
if (posNextComma == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
pos = posNextComma + 1;
|
||||
}
|
||||
|
||||
uint32_t offset = 0;
|
||||
uint32_t affinityMask = 0;
|
||||
for (uint32_t i = 0; i < affinityMaskBitSet.size(); i++) {
|
||||
for (uint32_t j = 0; j < affinityMaskBitSet[i].size(); j++) {
|
||||
if (affinityMaskBitSet[i][j] == true) {
|
||||
affinityMask |= (1UL << offset);
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
return affinityMask;
|
||||
}
|
||||
|
||||
ze_result_t DriverHandleImp::initialize(std::vector<std::unique_ptr<NEO::Device>> neoDevices) {
|
||||
|
||||
uint32_t affinityMask = std::numeric_limits<uint32_t>::max();
|
||||
|
||||
if (enablePciIdDeviceOrder) {
|
||||
sortNeoDevices(neoDevices);
|
||||
}
|
||||
|
||||
if (this->affinityMaskString.length() > 0) {
|
||||
affinityMask = parseAffinityMask(neoDevices);
|
||||
}
|
||||
|
||||
uint32_t currentMaskOffset = 0;
|
||||
for (auto &neoDevice : neoDevices) {
|
||||
if (!neoDevice->getHardwareInfo().capabilityTable.levelZeroSupported) {
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t currentDeviceMask = (affinityMask >> currentMaskOffset) & ((1UL << neoDevice->getNumAvailableDevices()) - 1);
|
||||
bool isDeviceExposed = currentDeviceMask ? true : false;
|
||||
|
||||
currentMaskOffset += neoDevice->getNumAvailableDevices();
|
||||
if (!isDeviceExposed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this->memoryManager == nullptr) {
|
||||
this->memoryManager = neoDevice->getMemoryManager();
|
||||
if (this->memoryManager == nullptr) {
|
||||
@ -270,7 +207,9 @@ ze_result_t DriverHandleImp::initialize(std::vector<std::unique_ptr<NEO::Device>
|
||||
|
||||
this->rootDeviceIndices.insert(neoDevice->getRootDeviceIndex());
|
||||
this->deviceBitfields.insert({neoDevice->getRootDeviceIndex(), neoDevice->getDeviceBitfield()});
|
||||
auto device = Device::create(this, neoDevice.release(), currentDeviceMask, false);
|
||||
|
||||
auto pNeoDevice = neoDevice.release();
|
||||
auto device = Device::create(this, pNeoDevice, pNeoDevice->getExecutionEnvironment()->rootDeviceEnvironments[pNeoDevice->getRootDeviceIndex()]->deviceAffinityMask, false);
|
||||
this->devices.push_back(device);
|
||||
}
|
||||
|
||||
@ -295,7 +234,6 @@ DriverHandle *DriverHandle::create(std::vector<std::unique_ptr<NEO::Device>> dev
|
||||
DriverHandleImp *driverHandle = new DriverHandleImp;
|
||||
UNRECOVERABLE_IF(nullptr == driverHandle);
|
||||
|
||||
driverHandle->affinityMaskString = envVariables.affinityMask;
|
||||
driverHandle->enableProgramDebugging = envVariables.programDebugging;
|
||||
driverHandle->enableSysman = envVariables.sysman;
|
||||
driverHandle->enablePciIdDeviceOrder = envVariables.pciIdDeviceOrder;
|
||||
|
@ -80,7 +80,6 @@ struct DriverHandleImp : public DriverHandle {
|
||||
size_t size,
|
||||
uint32_t rootDeviceIndex,
|
||||
uintptr_t *gpuAddress) override;
|
||||
uint32_t parseAffinityMask(std::vector<std::unique_ptr<NEO::Device>> &neoDevices);
|
||||
void createHostPointerManager();
|
||||
void sortNeoDevices(std::vector<std::unique_ptr<NEO::Device>> &neoDevices);
|
||||
|
||||
@ -91,7 +90,6 @@ struct DriverHandleImp : public DriverHandle {
|
||||
std::mutex sharedMakeResidentAllocationsLock;
|
||||
std::map<void *, NEO::GraphicsAllocation *> sharedMakeResidentAllocations;
|
||||
|
||||
std::string affinityMaskString = "";
|
||||
std::vector<Device *> devices;
|
||||
// Spec extensions
|
||||
const std::vector<std::pair<std::string, uint32_t>> extensionsSupported = {
|
||||
|
@ -132,6 +132,29 @@ set(TEST_MODULES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_modules/test_kernel.cl
|
||||
)
|
||||
|
||||
add_custom_target(copy_l0_test_files)
|
||||
|
||||
add_custom_command(TARGET copy_l0_test_files
|
||||
POST_BUILD
|
||||
COMMAND echo deleting and re-creating "${CUSTOM_COMMAND_BINARY_DIR}/test_files" ...
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory "${CUSTOM_COMMAND_BINARY_DIR}/test_files"
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${CUSTOM_COMMAND_BINARY_DIR}/test_files"
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/test_files"
|
||||
)
|
||||
set_target_properties(copy_l0_test_files PROPERTIES FOLDER ${TARGET_NAME_L0})
|
||||
|
||||
if(UNIX)
|
||||
add_custom_command(TARGET copy_l0_test_files
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory "${NEO_SOURCE_DIR}/opencl/test/unit_test/test_files/linux" "${CUSTOM_COMMAND_BINARY_DIR}/test_files/linux"
|
||||
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/test_files"
|
||||
)
|
||||
|
||||
add_dependencies(${TARGET_NAME}
|
||||
copy_l0_test_files
|
||||
)
|
||||
endif()
|
||||
|
||||
macro(macro_for_each_gen)
|
||||
foreach(PLATFORM_TYPE ${PLATFORM_TYPES})
|
||||
if(${GEN_TYPE}_HAS_${PLATFORM_TYPE})
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "shared/source/os_interface/device_factory.h"
|
||||
#include "shared/source/os_interface/hw_info_config.h"
|
||||
#include "shared/test/unit_test/helpers/debug_manager_state_restore.h"
|
||||
#include "shared/test/unit_test/helpers/ult_hw_config.h"
|
||||
#include "shared/test/unit_test/mocks/ult_device_factory.h"
|
||||
|
||||
#include "opencl/test/unit_test/mocks/mock_io_functions.h"
|
||||
@ -329,24 +330,12 @@ struct MaskArray {
|
||||
struct DriverTestMultipleDeviceWithAffinityMask : public ::testing::WithParamInterface<std::tuple<std::string, std::string>>,
|
||||
public ::testing::Test {
|
||||
void SetUp() override {
|
||||
DebugManager.flags.CreateMultipleRootDevices.set(numRootDevices);
|
||||
DebugManager.flags.CreateMultipleSubDevices.set(numSubDevices);
|
||||
VariableBackup<bool> mockDeviceFlagBackup(&MockDevice::createSingleDevice, false);
|
||||
|
||||
NEO::ExecutionEnvironment *executionEnvironment = new NEO::ExecutionEnvironment();
|
||||
executionEnvironment->prepareRootDeviceEnvironments(numRootDevices);
|
||||
for (auto i = 0u; i < executionEnvironment->rootDeviceEnvironments.size(); i++) {
|
||||
executionEnvironment->rootDeviceEnvironments[i]->setHwInfo(NEO::defaultHwInfo.get());
|
||||
}
|
||||
|
||||
for (auto i = 0u; i < executionEnvironment->rootDeviceEnvironments.size(); i++) {
|
||||
devices.push_back(std::unique_ptr<NEO::MockDevice>(NEO::MockDevice::createWithExecutionEnvironment<NEO::MockDevice>(
|
||||
NEO::defaultHwInfo.get(),
|
||||
executionEnvironment, i)));
|
||||
}
|
||||
}
|
||||
|
||||
DebugManagerStateRestore restorer;
|
||||
std::vector<std::unique_ptr<NEO::Device>> devices;
|
||||
|
||||
const uint32_t numRootDevices = 2u;
|
||||
const uint32_t numSubDevices = 4u;
|
||||
@ -354,17 +343,21 @@ struct DriverTestMultipleDeviceWithAffinityMask : public ::testing::WithParamInt
|
||||
|
||||
TEST_P(DriverTestMultipleDeviceWithAffinityMask,
|
||||
whenSettingAffinityMaskToRetrieveOneSubDeviceOnEachDeviceThenCorrectDevicesAreExposed) {
|
||||
VariableBackup<UltHwConfig> backup(&ultHwConfig);
|
||||
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
|
||||
|
||||
L0::DriverHandleImp *driverHandle = new DriverHandleImp;
|
||||
|
||||
std::string subDevice0String = std::get<0>(GetParam());
|
||||
uint32_t subDevice0Index = std::stoi(subDevice0String, nullptr, 0);
|
||||
|
||||
std::string subDevice1String = std::get<1>(GetParam());
|
||||
uint32_t subDevice1Index = std::stoi(subDevice1String, nullptr, 0);
|
||||
|
||||
constexpr uint32_t totalRootDevices = 2;
|
||||
|
||||
driverHandle->affinityMaskString = "0." + subDevice0String + "," + "1." + subDevice1String;
|
||||
DebugManager.flags.ZE_AFFINITY_MASK.set("0." + subDevice0String + "," + "1." + subDevice1String);
|
||||
|
||||
NEO::ExecutionEnvironment *executionEnvironment = new NEO::ExecutionEnvironment();
|
||||
auto devices = NEO::DeviceFactory::createDevices(*executionEnvironment);
|
||||
|
||||
ze_result_t res = driverHandle->initialize(std::move(devices));
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
|
||||
@ -383,24 +376,10 @@ TEST_P(DriverTestMultipleDeviceWithAffinityMask,
|
||||
ze_device_handle_t hDevice = phDevices[i];
|
||||
EXPECT_NE(nullptr, hDevice);
|
||||
|
||||
DeviceImp *device = reinterpret_cast<DeviceImp *>(L0::Device::fromHandle(hDevice));
|
||||
|
||||
uint32_t subDeviceCount = 0;
|
||||
res = zeDeviceGetSubDevices(hDevice, &subDeviceCount, nullptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
|
||||
EXPECT_EQ(1u, subDeviceCount);
|
||||
|
||||
ze_device_handle_t hSubDevice;
|
||||
res = zeDeviceGetSubDevices(hDevice, &subDeviceCount, &hSubDevice);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
|
||||
|
||||
DeviceImp *subDevice = reinterpret_cast<DeviceImp *>(L0::Device::fromHandle(hSubDevice));
|
||||
|
||||
if (i == 0) {
|
||||
EXPECT_EQ(subDevice->neoDevice, device->neoDevice->getDeviceById(subDevice0Index));
|
||||
} else {
|
||||
EXPECT_EQ(subDevice->neoDevice, device->neoDevice->getDeviceById(subDevice1Index));
|
||||
}
|
||||
EXPECT_EQ(0u, subDeviceCount);
|
||||
}
|
||||
|
||||
delete driverHandle;
|
||||
@ -409,14 +388,19 @@ TEST_P(DriverTestMultipleDeviceWithAffinityMask,
|
||||
|
||||
TEST_P(DriverTestMultipleDeviceWithAffinityMask,
|
||||
whenSettingAffinityMaskToRetrieveAllDevicesInOneDeviceAndOneSubDeviceInOtherThenCorrectDevicesAreExposed) {
|
||||
VariableBackup<UltHwConfig> backup(&ultHwConfig);
|
||||
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
|
||||
|
||||
L0::DriverHandleImp *driverHandle = new DriverHandleImp;
|
||||
|
||||
std::string subDevice1String = std::get<1>(GetParam());
|
||||
uint32_t subDevice1Index = std::stoi(subDevice1String, nullptr, 0);
|
||||
|
||||
constexpr uint32_t totalRootDevices = 2;
|
||||
|
||||
driverHandle->affinityMaskString = "0,1." + subDevice1String;
|
||||
DebugManager.flags.ZE_AFFINITY_MASK.set("0,1." + subDevice1String);
|
||||
|
||||
NEO::ExecutionEnvironment *executionEnvironment = new NEO::ExecutionEnvironment();
|
||||
auto devices = NEO::DeviceFactory::createDevices(*executionEnvironment);
|
||||
|
||||
ze_result_t res = driverHandle->initialize(std::move(devices));
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
|
||||
@ -435,8 +419,6 @@ TEST_P(DriverTestMultipleDeviceWithAffinityMask,
|
||||
ze_device_handle_t hDevice = phDevices[i];
|
||||
EXPECT_NE(nullptr, hDevice);
|
||||
|
||||
DeviceImp *device = reinterpret_cast<DeviceImp *>(L0::Device::fromHandle(hDevice));
|
||||
|
||||
uint32_t subDeviceCount = 0;
|
||||
res = zeDeviceGetSubDevices(hDevice, &subDeviceCount, nullptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
|
||||
@ -447,10 +429,7 @@ TEST_P(DriverTestMultipleDeviceWithAffinityMask,
|
||||
res = zeDeviceGetSubDevices(hDevice, &subDeviceCount, &hSubDevice);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
|
||||
|
||||
DeviceImp *subDevice = reinterpret_cast<DeviceImp *>(L0::Device::fromHandle(hSubDevice));
|
||||
|
||||
EXPECT_EQ(1u, subDeviceCount);
|
||||
EXPECT_EQ(subDevice->neoDevice, device->neoDevice->getDeviceById(subDevice1Index));
|
||||
EXPECT_EQ(0u, subDeviceCount);
|
||||
}
|
||||
}
|
||||
|
||||
@ -467,11 +446,17 @@ INSTANTIATE_TEST_SUITE_P(DriverTestMultipleDeviceWithAffinityMaskTests,
|
||||
|
||||
TEST_F(DriverTestMultipleDeviceWithAffinityMask,
|
||||
whenSettingAffinityMaskWithDeviceLargerThanAvailableDevicesThenRootDeviceValueIsIgnored) {
|
||||
VariableBackup<UltHwConfig> backup(&ultHwConfig);
|
||||
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
|
||||
|
||||
L0::DriverHandleImp *driverHandle = new DriverHandleImp;
|
||||
|
||||
constexpr uint32_t totalRootDevices = 2;
|
||||
uint32_t subDevice1Index = 0;
|
||||
driverHandle->affinityMaskString = "0,23,1." + std::to_string(subDevice1Index);
|
||||
DebugManager.flags.ZE_AFFINITY_MASK.set("0,23,1." + std::to_string(subDevice1Index));
|
||||
|
||||
NEO::ExecutionEnvironment *executionEnvironment = new NEO::ExecutionEnvironment();
|
||||
auto devices = NEO::DeviceFactory::createDevices(*executionEnvironment);
|
||||
|
||||
ze_result_t res = driverHandle->initialize(std::move(devices));
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
|
||||
@ -490,8 +475,6 @@ TEST_F(DriverTestMultipleDeviceWithAffinityMask,
|
||||
ze_device_handle_t hDevice = phDevices[i];
|
||||
EXPECT_NE(nullptr, hDevice);
|
||||
|
||||
DeviceImp *device = reinterpret_cast<DeviceImp *>(L0::Device::fromHandle(hDevice));
|
||||
|
||||
uint32_t subDeviceCount = 0;
|
||||
res = zeDeviceGetSubDevices(hDevice, &subDeviceCount, nullptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
|
||||
@ -501,11 +484,7 @@ TEST_F(DriverTestMultipleDeviceWithAffinityMask,
|
||||
ze_device_handle_t hSubDevice;
|
||||
res = zeDeviceGetSubDevices(hDevice, &subDeviceCount, &hSubDevice);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
|
||||
|
||||
DeviceImp *subDevice = reinterpret_cast<DeviceImp *>(L0::Device::fromHandle(hSubDevice));
|
||||
|
||||
EXPECT_EQ(1u, subDeviceCount);
|
||||
EXPECT_EQ(subDevice->neoDevice, device->neoDevice->getDeviceById(subDevice1Index));
|
||||
EXPECT_EQ(0u, subDeviceCount);
|
||||
}
|
||||
}
|
||||
|
||||
@ -515,9 +494,15 @@ TEST_F(DriverTestMultipleDeviceWithAffinityMask,
|
||||
|
||||
TEST_F(DriverTestMultipleDeviceWithAffinityMask,
|
||||
whenSettingAffinityMaskWithSubDeviceLargerThanAvailableSubDevicesThenSubDeviceValueIsIgnored) {
|
||||
VariableBackup<UltHwConfig> backup(&ultHwConfig);
|
||||
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
|
||||
|
||||
L0::DriverHandleImp *driverHandle = new DriverHandleImp;
|
||||
|
||||
driverHandle->affinityMaskString = "0,1.77";
|
||||
DebugManager.flags.ZE_AFFINITY_MASK.set("0,1.77");
|
||||
|
||||
NEO::ExecutionEnvironment *executionEnvironment = new NEO::ExecutionEnvironment();
|
||||
auto devices = NEO::DeviceFactory::createDevices(*executionEnvironment);
|
||||
|
||||
ze_result_t res = driverHandle->initialize(std::move(devices));
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
|
||||
|
@ -230,7 +230,7 @@ void ClDevice::initializeCaps() {
|
||||
deviceInfo.deviceAvailable = CL_TRUE;
|
||||
deviceInfo.compilerAvailable = CL_TRUE;
|
||||
deviceInfo.parentDevice = nullptr;
|
||||
deviceInfo.partitionMaxSubDevices = HwHelper::getSubDevicesCount(&hwInfo);
|
||||
deviceInfo.partitionMaxSubDevices = device.getNumAvailableDevices();
|
||||
if (deviceInfo.partitionMaxSubDevices > 1) {
|
||||
deviceInfo.partitionProperties[0] = CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN;
|
||||
deviceInfo.partitionProperties[1] = 0;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019-2020 Intel Corporation
|
||||
* Copyright (C) 2019-2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@ -201,7 +201,6 @@ TEST(SubDevicesTest, givenDeviceWithoutSubDevicesWhenGettingDeviceByIdZeroThenGe
|
||||
|
||||
EXPECT_EQ(1u, device->getNumAvailableDevices());
|
||||
EXPECT_EQ(device.get(), device->getDeviceById(0u));
|
||||
EXPECT_THROW(device->getDeviceById(1), std::exception);
|
||||
}
|
||||
|
||||
TEST(SubDevicesTest, givenDeviceWithSubDevicesWhenGettingDeviceByIdThenGetCorrectSubDevice) {
|
||||
@ -245,7 +244,7 @@ TEST(RootDevicesTest, givenRootDeviceWithSubdevicesWhenCreateEnginesThenDeviceCr
|
||||
|
||||
auto executionEnvironment = new MockExecutionEnvironment;
|
||||
MockDevice device(executionEnvironment, 0);
|
||||
device.subdevices.resize(2u);
|
||||
device.numSubDevices = 2;
|
||||
EXPECT_EQ(0u, device.engines.size());
|
||||
device.createEngines();
|
||||
EXPECT_EQ(1u, device.engines.size());
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include "shared/source/os_interface/os_interface.h"
|
||||
#include "shared/source/os_interface/os_library.h"
|
||||
#include "shared/test/unit_test/helpers/debug_manager_state_restore.h"
|
||||
#include "shared/test/unit_test/helpers/ult_hw_config.h"
|
||||
#include "shared/test/unit_test/helpers/variable_backup.h"
|
||||
#include "shared/test/unit_test/mocks/ult_device_factory.h"
|
||||
|
||||
#include "opencl/source/platform/platform.h"
|
||||
@ -94,6 +96,67 @@ TEST_F(DeviceFactoryTest, WhenOverridingUsingDebugManagerThenOverridesAreApplied
|
||||
hwInfo->capabilityTable.kmdNotifyProperties.delayQuickKmdSleepForSporadicWaitsMicroseconds);
|
||||
}
|
||||
|
||||
TEST_F(DeviceFactoryTest, givenZeAffinityMaskSetWhenCreateDevicesThenProperNumberOfDevicesIsReturned) {
|
||||
DebugManagerStateRestore restorer;
|
||||
DebugManager.flags.CreateMultipleRootDevices.set(5);
|
||||
DebugManager.flags.CreateMultipleSubDevices.set(4);
|
||||
DebugManager.flags.ZE_AFFINITY_MASK.set("1.0,2.3,2.1,1.3,0,2.0,4.0,4.2,4.3,4.1");
|
||||
VariableBackup<UltHwConfig> backup(&ultHwConfig);
|
||||
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
|
||||
|
||||
auto devices = DeviceFactory::createDevices(*executionEnvironment);
|
||||
|
||||
EXPECT_EQ(devices.size(), 4u);
|
||||
EXPECT_EQ(devices[0]->getNumAvailableDevices(), 4u);
|
||||
EXPECT_EQ(devices[1]->getNumAvailableDevices(), 2u);
|
||||
EXPECT_EQ(devices[2]->getNumAvailableDevices(), 3u);
|
||||
EXPECT_EQ(devices[3]->getNumAvailableDevices(), 4u);
|
||||
}
|
||||
|
||||
TEST_F(DeviceFactoryTest, givenZeAffinityMaskSetToGreaterRootDeviceThanAvailableWhenCreateDevicesThenProperNumberOfDevicesIsReturned) {
|
||||
DebugManagerStateRestore restorer;
|
||||
DebugManager.flags.CreateMultipleRootDevices.set(2);
|
||||
DebugManager.flags.CreateMultipleSubDevices.set(4);
|
||||
DebugManager.flags.ZE_AFFINITY_MASK.set("0,92,1.1");
|
||||
VariableBackup<UltHwConfig> backup(&ultHwConfig);
|
||||
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
|
||||
|
||||
auto devices = DeviceFactory::createDevices(*executionEnvironment);
|
||||
|
||||
EXPECT_EQ(devices.size(), 2u);
|
||||
EXPECT_EQ(devices[0]->getNumAvailableDevices(), 4u);
|
||||
EXPECT_EQ(devices[1]->getNumAvailableDevices(), 1u);
|
||||
}
|
||||
|
||||
TEST_F(DeviceFactoryTest, givenZeAffinityMaskSetToGreaterSubDeviceThanAvailableWhenCreateDevicesThenProperNumberOfDevicesIsReturned) {
|
||||
DebugManagerStateRestore restorer;
|
||||
DebugManager.flags.CreateMultipleRootDevices.set(2);
|
||||
DebugManager.flags.CreateMultipleSubDevices.set(4);
|
||||
DebugManager.flags.ZE_AFFINITY_MASK.set("0,1.54");
|
||||
VariableBackup<UltHwConfig> backup(&ultHwConfig);
|
||||
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
|
||||
|
||||
auto devices = DeviceFactory::createDevices(*executionEnvironment);
|
||||
|
||||
EXPECT_EQ(devices.size(), 1u);
|
||||
EXPECT_EQ(devices[0]->getNumAvailableDevices(), 4u);
|
||||
}
|
||||
|
||||
TEST_F(DeviceFactoryTest, givenZeAffinityMaskSetToRootDevicesOnlyWhenCreateDevicesThenProperNumberOfDevicesIsReturned) {
|
||||
DebugManagerStateRestore restorer;
|
||||
DebugManager.flags.CreateMultipleRootDevices.set(2);
|
||||
DebugManager.flags.CreateMultipleSubDevices.set(4);
|
||||
DebugManager.flags.ZE_AFFINITY_MASK.set("0,1");
|
||||
VariableBackup<UltHwConfig> backup(&ultHwConfig);
|
||||
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
|
||||
|
||||
auto devices = DeviceFactory::createDevices(*executionEnvironment);
|
||||
|
||||
EXPECT_EQ(devices.size(), 2u);
|
||||
EXPECT_EQ(devices[0]->getNumAvailableDevices(), 4u);
|
||||
EXPECT_EQ(devices[1]->getNumAvailableDevices(), 4u);
|
||||
}
|
||||
|
||||
TEST_F(DeviceFactoryTest, WhenOverridingEngineTypeThenDebugEngineIsReported) {
|
||||
DebugManagerStateRestore dbgRestorer;
|
||||
int32_t debugEngineType = 2;
|
||||
|
@ -9,6 +9,7 @@ AUBDumpFilterKernelName = unk
|
||||
AUBDumpToggleFileName = unk
|
||||
OverrideGdiPath = unk
|
||||
AubDumpAddMmioRegistersList = unk
|
||||
ZE_AFFINITY_MASK = default
|
||||
AUBDumpFilterNamedKernelStartIdx = 0
|
||||
AUBDumpFilterNamedKernelEndIdx = -1
|
||||
AUBDumpSubCaptureMode = 0
|
||||
|
@ -12,3 +12,4 @@
|
||||
DECLARE_DEBUG_VARIABLE(bool, MakeAllBuffersResident, false, "Make all buffers resident after creation")
|
||||
DECLARE_DEBUG_VARIABLE(int32_t, OverrideDefaultFP64Settings, -1, "-1: dont override, 0: disable, 1: enable.")
|
||||
DECLARE_DEBUG_VARIABLE(int32_t, EnableCrossDeviceAccess, -1, "-1: default behavior, 0: disabled, 1: enabled, Allows one device to access another device's memory")
|
||||
DECLARE_DEBUG_VARIABLE(std::string, ZE_AFFINITY_MASK, std::string("default"), "Refer to the Level Zero Specification for a desricption")
|
||||
|
@ -33,7 +33,7 @@ RootDevice::~RootDevice() {
|
||||
}
|
||||
|
||||
uint32_t RootDevice::getNumSubDevices() const {
|
||||
return static_cast<uint32_t>(subdevices.size());
|
||||
return this->numSubDevices;
|
||||
}
|
||||
|
||||
BindlessHeapsHelper *RootDevice::getBindlessHeapsHelper() const {
|
||||
@ -51,10 +51,10 @@ uint32_t RootDevice::getNumAvailableDevices() const {
|
||||
}
|
||||
|
||||
Device *RootDevice::getDeviceById(uint32_t deviceId) const {
|
||||
UNRECOVERABLE_IF(deviceId >= getNumAvailableDevices());
|
||||
if (subdevices.empty()) {
|
||||
return const_cast<RootDevice *>(this);
|
||||
}
|
||||
UNRECOVERABLE_IF(deviceId >= subdevices.size());
|
||||
return subdevices[deviceId];
|
||||
}
|
||||
|
||||
@ -67,19 +67,26 @@ SubDevice *RootDevice::createSubDevice(uint32_t subDeviceIndex) {
|
||||
}
|
||||
|
||||
bool RootDevice::createDeviceImpl() {
|
||||
auto numSubDevices = HwHelper::getSubDevicesCount(&getHardwareInfo());
|
||||
auto deviceMask = executionEnvironment->rootDeviceEnvironments[this->rootDeviceIndex]->deviceAffinityMask;
|
||||
deviceBitfield = maxNBitValue(HwHelper::getSubDevicesCount(&getHardwareInfo()));
|
||||
deviceBitfield &= deviceMask;
|
||||
numSubDevices = static_cast<uint32_t>(deviceBitfield.count());
|
||||
if (numSubDevices == 1) {
|
||||
numSubDevices = 0;
|
||||
}
|
||||
UNRECOVERABLE_IF(!subdevices.empty());
|
||||
subdevices.resize(numSubDevices, nullptr);
|
||||
for (auto i = 0u; i < numSubDevices; i++) {
|
||||
|
||||
auto subDevice = createSubDevice(i);
|
||||
if (!subDevice) {
|
||||
return false;
|
||||
if (numSubDevices) {
|
||||
subdevices.resize(HwHelper::getSubDevicesCount(&getHardwareInfo()), nullptr);
|
||||
for (auto i = 0u; i < HwHelper::getSubDevicesCount(&getHardwareInfo()); i++) {
|
||||
if (!deviceBitfield.test(i)) {
|
||||
continue;
|
||||
}
|
||||
auto subDevice = createSubDevice(i);
|
||||
if (!subDevice) {
|
||||
return false;
|
||||
}
|
||||
subdevices[i] = subDevice;
|
||||
}
|
||||
subdevices[i] = subDevice;
|
||||
}
|
||||
auto status = Device::createDeviceImpl();
|
||||
if (!status) {
|
||||
@ -90,8 +97,8 @@ bool RootDevice::createDeviceImpl() {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
DeviceBitfield RootDevice::getDeviceBitfield() const {
|
||||
DeviceBitfield deviceBitfield{static_cast<uint32_t>(maxNBitValue(getNumAvailableDevices()))};
|
||||
return deviceBitfield;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019-2020 Intel Corporation
|
||||
* Copyright (C) 2019-2021 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@ -33,6 +33,8 @@ class RootDevice : public Device {
|
||||
|
||||
std::vector<SubDevice *> subdevices;
|
||||
const uint32_t rootDeviceIndex;
|
||||
DeviceBitfield deviceBitfield = DeviceBitfield{1u};
|
||||
uint32_t numSubDevices = 0;
|
||||
std::unique_ptr<BindlessHeapsHelper> bindlessHeapHelper;
|
||||
};
|
||||
} // namespace NEO
|
||||
|
@ -78,4 +78,77 @@ void ExecutionEnvironment::prepareRootDeviceEnvironments(uint32_t numRootDevices
|
||||
}
|
||||
}
|
||||
}
|
||||
void ExecutionEnvironment::parseAffinityMask() {
|
||||
auto affinityMaskString = DebugManager.flags.ZE_AFFINITY_MASK.get();
|
||||
|
||||
if (affinityMaskString.compare("default") == 0 ||
|
||||
affinityMaskString.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::vector<bool>> affinityMaskBitSet(rootDeviceEnvironments.size());
|
||||
for (uint32_t i = 0; i < affinityMaskBitSet.size(); i++) {
|
||||
auto hwInfo = rootDeviceEnvironments[i]->getHardwareInfo();
|
||||
affinityMaskBitSet[i].resize(HwHelper::getSubDevicesCount(hwInfo));
|
||||
}
|
||||
|
||||
size_t pos = 0;
|
||||
while (pos < affinityMaskString.size()) {
|
||||
size_t posNextDot = affinityMaskString.find_first_of(".", pos);
|
||||
size_t posNextComma = affinityMaskString.find_first_of(",", pos);
|
||||
std::string rootDeviceString = affinityMaskString.substr(pos, std::min(posNextDot, posNextComma) - pos);
|
||||
uint32_t rootDeviceIndex = static_cast<uint32_t>(std::stoul(rootDeviceString, nullptr, 0));
|
||||
if (rootDeviceIndex < rootDeviceEnvironments.size()) {
|
||||
pos += rootDeviceString.size();
|
||||
if (posNextDot != std::string::npos &&
|
||||
affinityMaskString.at(pos) == '.' && posNextDot < posNextComma) {
|
||||
pos++;
|
||||
std::string subDeviceString = affinityMaskString.substr(pos, posNextComma - pos);
|
||||
uint32_t subDeviceIndex = static_cast<uint32_t>(std::stoul(subDeviceString, nullptr, 0));
|
||||
auto hwInfo = rootDeviceEnvironments[rootDeviceIndex]->getHardwareInfo();
|
||||
if (subDeviceIndex < HwHelper::getSubDevicesCount(hwInfo)) {
|
||||
affinityMaskBitSet[rootDeviceIndex][subDeviceIndex] = true;
|
||||
}
|
||||
} else {
|
||||
std::fill(affinityMaskBitSet[rootDeviceIndex].begin(),
|
||||
affinityMaskBitSet[rootDeviceIndex].end(),
|
||||
true);
|
||||
}
|
||||
}
|
||||
if (posNextComma == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
pos = posNextComma + 1;
|
||||
}
|
||||
|
||||
uint32_t offset = 0;
|
||||
uint32_t affinityMask = 0;
|
||||
for (uint32_t i = 0; i < affinityMaskBitSet.size(); i++) {
|
||||
for (uint32_t j = 0; j < affinityMaskBitSet[i].size(); j++) {
|
||||
if (affinityMaskBitSet[i][j] == true) {
|
||||
affinityMask |= (1UL << offset);
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t currentMaskOffset = 0;
|
||||
std::vector<std::unique_ptr<RootDeviceEnvironment>> filteredEnvironments;
|
||||
for (size_t i = 0u; i < this->rootDeviceEnvironments.size(); i++) {
|
||||
auto hwInfo = rootDeviceEnvironments[i]->getHardwareInfo();
|
||||
|
||||
uint32_t currentDeviceMask = (affinityMask >> currentMaskOffset) & ((1UL << HwHelper::getSubDevicesCount(hwInfo)) - 1);
|
||||
bool isDeviceExposed = currentDeviceMask > 0;
|
||||
|
||||
currentMaskOffset += HwHelper::getSubDevicesCount(hwInfo);
|
||||
if (!isDeviceExposed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rootDeviceEnvironments[i]->deviceAffinityMask = currentDeviceMask;
|
||||
filteredEnvironments.emplace_back(rootDeviceEnvironments[i].release());
|
||||
}
|
||||
|
||||
rootDeviceEnvironments.swap(filteredEnvironments);
|
||||
}
|
||||
} // namespace NEO
|
||||
|
@ -24,6 +24,7 @@ class ExecutionEnvironment : public ReferenceTrackedObject<ExecutionEnvironment>
|
||||
MOCKABLE_VIRTUAL bool initializeMemoryManager();
|
||||
void calculateMaxOsContextCount();
|
||||
void prepareRootDeviceEnvironments(uint32_t numRootDevices);
|
||||
void parseAffinityMask();
|
||||
void setDebuggingEnabled() {
|
||||
debuggingEnabled = true;
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ class MemoryOperationsHandler;
|
||||
class OSInterface;
|
||||
struct HardwareInfo;
|
||||
|
||||
constexpr uint32_t allSubDevicesActive = std::numeric_limits<uint32_t>::max();
|
||||
|
||||
struct RootDeviceEnvironment {
|
||||
protected:
|
||||
std::unique_ptr<HardwareInfo> hwInfo;
|
||||
@ -62,6 +64,8 @@ struct RootDeviceEnvironment {
|
||||
std::unique_ptr<Debugger> debugger;
|
||||
ExecutionEnvironment &executionEnvironment;
|
||||
|
||||
uint32_t deviceAffinityMask = allSubDevicesActive;
|
||||
|
||||
private:
|
||||
std::mutex mtx;
|
||||
};
|
||||
|
@ -73,6 +73,7 @@ bool DeviceFactory::prepareDeviceEnvironmentsForProductFamilyOverride(ExecutionE
|
||||
}
|
||||
}
|
||||
|
||||
executionEnvironment.parseAffinityMask();
|
||||
executionEnvironment.calculateMaxOsContextCount();
|
||||
return true;
|
||||
}
|
||||
@ -119,6 +120,7 @@ bool DeviceFactory::prepareDeviceEnvironments(ExecutionEnvironment &executionEnv
|
||||
rootDeviceIndex++;
|
||||
}
|
||||
|
||||
executionEnvironment.parseAffinityMask();
|
||||
executionEnvironment.calculateMaxOsContextCount();
|
||||
|
||||
return true;
|
||||
|
@ -54,6 +54,7 @@ class MockDevice : public RootDevice {
|
||||
using RootDevice::defaultEngineIndex;
|
||||
using RootDevice::getDeviceBitfield;
|
||||
using RootDevice::initializeRootCommandStreamReceiver;
|
||||
using RootDevice::numSubDevices;
|
||||
using RootDevice::subdevices;
|
||||
|
||||
void setOSTime(OSTime *osTime);
|
||||
|
Reference in New Issue
Block a user