Use ZE_AFFINITY_MASK for neo devices

Resolves: NEO-5438

Signed-off-by: Lukasz Jobczyk <lukasz.jobczyk@intel.com>
This commit is contained in:
Lukasz Jobczyk
2021-01-25 09:24:00 +00:00
committed by Compute-Runtime-Automation
parent 2eaf830aff
commit 8ed14d0c9f
16 changed files with 229 additions and 131 deletions

View File

@ -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;

View File

@ -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 = {

View File

@ -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})

View File

@ -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);

View File

@ -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;

View File

@ -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());

View File

@ -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;

View File

@ -9,6 +9,7 @@ AUBDumpFilterKernelName = unk
AUBDumpToggleFileName = unk
OverrideGdiPath = unk
AubDumpAddMmioRegistersList = unk
ZE_AFFINITY_MASK = default
AUBDumpFilterNamedKernelStartIdx = 0
AUBDumpFilterNamedKernelEndIdx = -1
AUBDumpSubCaptureMode = 0

View File

@ -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")

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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;

View File

@ -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);