Skip to content

Commit 19dbfb7

Browse files
authored
[UR][L0] Create pool descriptors from subdevices... (#17465)
stored in device handle. The pool_descriptor::create function retrieves subdevices partitioned with UR_DEVICE_PARTITION_BY_CSLICE by default. This causes problem in a SYCL scenario where user obtains subdevices partitioned with eg. sycl::info::partition_affinity_domain::numa.
1 parent c0ee586 commit 19dbfb7

File tree

5 files changed

+50
-124
lines changed

5 files changed

+50
-124
lines changed

unified-runtime/source/adapters/level_zero/device.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,19 @@ struct ur_device_handle_t_ : _ur_object {
243243
// unique ephemeral identifer of the device in the adapter
244244
std::optional<DeviceId> Id;
245245
};
246+
247+
inline std::vector<ur_device_handle_t>
248+
CollectDevicesAndSubDevices(const std::vector<ur_device_handle_t> &Devices) {
249+
std::vector<ur_device_handle_t> DevicesAndSubDevices;
250+
std::function<void(const std::vector<ur_device_handle_t> &)>
251+
CollectDevicesAndSubDevicesRec =
252+
[&](const std::vector<ur_device_handle_t> &Devices) {
253+
for (auto &Device : Devices) {
254+
DevicesAndSubDevices.push_back(Device);
255+
CollectDevicesAndSubDevicesRec(Device->SubDevices);
256+
}
257+
};
258+
CollectDevicesAndSubDevicesRec(Devices);
259+
260+
return DevicesAndSubDevices;
261+
}

unified-runtime/source/adapters/level_zero/usm.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -949,12 +949,9 @@ ur_usm_pool_handle_t_::ur_usm_pool_handle_t_(ur_context_handle_t Context,
949949
}
950950
}
951951

952-
auto [Ret, Descriptors] = usm::pool_descriptor::create(this, Context);
953-
if (Ret) {
954-
logger::error("urUSMPoolCreate: failed to create pool descriptors");
955-
throw UsmAllocationException(Ret);
956-
}
957-
952+
auto DevicesAndSubDevices = CollectDevicesAndSubDevices(Context->Devices);
953+
auto Descriptors = usm::pool_descriptor::createFromDevices(
954+
this, Context, DevicesAndSubDevices);
958955
for (auto &Desc : Descriptors) {
959956
umf::pool_unique_handle_t Pool = nullptr;
960957
if (IsProxy) {
@@ -965,7 +962,7 @@ ur_usm_pool_handle_t_::ur_usm_pool_handle_t_(ur_context_handle_t Context,
965962
Pool = usm::makeDisjointPool(MakeProvider(&Desc), PoolConfig);
966963
}
967964

968-
Ret = PoolManager.addPool(Desc, std::move(Pool));
965+
auto Ret = PoolManager.addPool(Desc, std::move(Pool));
969966
if (Ret) {
970967
logger::error("urUSMPoolCreate: failed to store UMF pool");
971968
throw UsmAllocationException(Ret);

unified-runtime/source/adapters/level_zero/v2/usm.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,10 @@ ur_usm_pool_handle_t_::ur_usm_pool_handle_t_(ur_context_handle_t hContext,
166166
logger::info("USM pooling is disabled. Skiping pool limits adjustment.");
167167
}
168168

169-
auto [result, descriptors] = usm::pool_descriptor::create(this, hContext);
170-
if (result != UR_RESULT_SUCCESS) {
171-
throw result;
172-
}
173-
169+
auto devicesAndSubDevices =
170+
CollectDevicesAndSubDevices(hContext->getDevices());
171+
auto descriptors = usm::pool_descriptor::createFromDevices(
172+
this, hContext, devicesAndSubDevices);
174173
for (auto &desc : descriptors) {
175174
if (disjointPoolConfigs.has_value()) {
176175
auto &poolConfig =

unified-runtime/source/common/ur_pool_manager.hpp

Lines changed: 8 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -61,104 +61,12 @@ struct pool_descriptor {
6161
bool operator==(const pool_descriptor &other) const;
6262
friend std::ostream &operator<<(std::ostream &os,
6363
const pool_descriptor &desc);
64-
static std::pair<ur_result_t, std::vector<pool_descriptor>>
65-
create(ur_usm_pool_handle_t poolHandle, ur_context_handle_t hContext);
64+
static std::vector<pool_descriptor>
65+
createFromDevices(ur_usm_pool_handle_t poolHandle,
66+
ur_context_handle_t hContext,
67+
const std::vector<ur_device_handle_t> &devices);
6668
};
6769

68-
static inline std::pair<ur_result_t, std::vector<ur_device_handle_t>>
69-
urGetSubDevices(ur_device_handle_t hDevice) {
70-
static detail::ddiTables ddi;
71-
72-
uint32_t nComputeUnits;
73-
auto ret = ddi.deviceDdiTable.pfnGetInfo(
74-
hDevice, UR_DEVICE_INFO_MAX_COMPUTE_UNITS, sizeof(nComputeUnits),
75-
&nComputeUnits, nullptr);
76-
if (ret != UR_RESULT_SUCCESS) {
77-
return {ret, {}};
78-
}
79-
80-
ur_device_partition_property_t prop;
81-
prop.type = UR_DEVICE_PARTITION_BY_CSLICE;
82-
prop.value.affinity_domain = 0;
83-
84-
ur_device_partition_properties_t properties{
85-
UR_STRUCTURE_TYPE_DEVICE_PARTITION_PROPERTIES,
86-
nullptr,
87-
&prop,
88-
1,
89-
};
90-
91-
// Get the number of devices that will be created
92-
uint32_t deviceCount;
93-
ret = ddi.deviceDdiTable.pfnPartition(hDevice, &properties, 0, nullptr,
94-
&deviceCount);
95-
if (ret != UR_RESULT_SUCCESS) {
96-
return {ret, {}};
97-
}
98-
99-
std::vector<ur_device_handle_t> sub_devices(deviceCount);
100-
ret = ddi.deviceDdiTable.pfnPartition(
101-
hDevice, &properties, static_cast<uint32_t>(sub_devices.size()),
102-
sub_devices.data(), nullptr);
103-
if (ret != UR_RESULT_SUCCESS) {
104-
return {ret, {}};
105-
}
106-
107-
return {UR_RESULT_SUCCESS, sub_devices};
108-
}
109-
110-
inline std::pair<ur_result_t, std::vector<ur_device_handle_t>>
111-
urGetAllDevicesAndSubDevices(ur_context_handle_t hContext) {
112-
static detail::ddiTables ddi;
113-
114-
size_t deviceCount = 0;
115-
auto ret = ddi.contextDdiTable.pfnGetInfo(
116-
hContext, UR_CONTEXT_INFO_NUM_DEVICES, sizeof(deviceCount), &deviceCount,
117-
nullptr);
118-
if (ret != UR_RESULT_SUCCESS || deviceCount == 0) {
119-
return {ret, {}};
120-
}
121-
122-
std::vector<ur_device_handle_t> devices(deviceCount);
123-
ret = ddi.contextDdiTable.pfnGetInfo(hContext, UR_CONTEXT_INFO_DEVICES,
124-
sizeof(ur_device_handle_t) * deviceCount,
125-
devices.data(), nullptr);
126-
if (ret != UR_RESULT_SUCCESS) {
127-
return {ret, {}};
128-
}
129-
130-
std::vector<ur_device_handle_t> devicesAndSubDevices;
131-
std::function<ur_result_t(ur_device_handle_t)> addPoolsForDevicesRec =
132-
[&](ur_device_handle_t hDevice) {
133-
devicesAndSubDevices.push_back(hDevice);
134-
auto [ret, subDevices] = urGetSubDevices(hDevice);
135-
if (ret != UR_RESULT_SUCCESS) {
136-
return ret;
137-
}
138-
for (auto &subDevice : subDevices) {
139-
ret = addPoolsForDevicesRec(subDevice);
140-
if (ret != UR_RESULT_SUCCESS) {
141-
return ret;
142-
}
143-
}
144-
return UR_RESULT_SUCCESS;
145-
};
146-
147-
for (size_t i = 0; i < deviceCount; i++) {
148-
ret = addPoolsForDevicesRec(devices[i]);
149-
if (ret != UR_RESULT_SUCCESS) {
150-
if (ret == UR_RESULT_ERROR_UNSUPPORTED_FEATURE) {
151-
// Return main devices when sub-devices are unsupported.
152-
return {ret, std::move(devices)};
153-
}
154-
155-
return {ret, {}};
156-
}
157-
}
158-
159-
return {UR_RESULT_SUCCESS, devicesAndSubDevices};
160-
}
161-
16270
static inline bool
16371
isSharedAllocationReadOnlyOnDevice(const pool_descriptor &desc) {
16472
return desc.type == UR_USM_TYPE_SHARED && desc.deviceReadOnly;
@@ -205,14 +113,9 @@ inline std::ostream &operator<<(std::ostream &os, const pool_descriptor &desc) {
205113
return os;
206114
}
207115

208-
inline std::pair<ur_result_t, std::vector<pool_descriptor>>
209-
pool_descriptor::create(ur_usm_pool_handle_t poolHandle,
210-
ur_context_handle_t hContext) {
211-
auto [ret, devices] = urGetAllDevicesAndSubDevices(hContext);
212-
if (ret != UR_RESULT_SUCCESS) {
213-
return {ret, {}};
214-
}
215-
116+
inline std::vector<pool_descriptor> pool_descriptor::createFromDevices(
117+
ur_usm_pool_handle_t poolHandle, ur_context_handle_t hContext,
118+
const std::vector<ur_device_handle_t> &devices) {
216119
std::vector<pool_descriptor> descriptors;
217120
pool_descriptor &desc = descriptors.emplace_back();
218121
desc.poolHandle = poolHandle;
@@ -245,7 +148,7 @@ pool_descriptor::create(ur_usm_pool_handle_t poolHandle,
245148
}
246149
}
247150

248-
return {ret, descriptors};
151+
return descriptors;
249152
}
250153

251154
template <typename D> struct pool_manager {

unified-runtime/test/usm/usmPoolManager.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,22 @@ bool compareConfigs(const usm::DisjointPoolAllConfigs &left,
3939
right.Configs[usm::DisjointPoolMemType::SharedReadOnly]);
4040
}
4141

42+
static std::vector<ur_device_handle_t>
43+
collectDeviceHandles(const std::vector<uur::DeviceTuple> &testDevices) {
44+
std::vector<ur_device_handle_t> devices(testDevices.size());
45+
std::for_each(
46+
testDevices.begin(), testDevices.end(),
47+
[&devices](uur::DeviceTuple tuple) { devices.push_back(tuple.device); });
48+
49+
return devices;
50+
}
51+
4252
TEST_P(urUsmPoolDescriptorTest, poolIsPerContextTypeAndDevice) {
43-
auto &devices = uur::DevicesEnvironment::instance->devices;
53+
auto &testDevices = uur::DevicesEnvironment::instance->devices;
4454

45-
auto [ret, pool_descriptors] =
46-
usm::pool_descriptor::create(nullptr, this->context);
47-
ASSERT_EQ(ret, UR_RESULT_SUCCESS);
55+
auto devices = collectDeviceHandles(testDevices);
56+
auto pool_descriptors =
57+
usm::pool_descriptor::createFromDevices(nullptr, this->context, devices);
4858

4959
size_t hostPools = 0;
5060
size_t devicePools = 0;
@@ -77,9 +87,10 @@ TEST_P(urUsmPoolDescriptorTest, poolIsPerContextTypeAndDevice) {
7787
struct urUsmPoolManagerTest : public uur::urContextTest {
7888
void SetUp() override {
7989
UUR_RETURN_ON_FATAL_FAILURE(urContextTest::SetUp());
80-
auto [ret, descs] = usm::pool_descriptor::create(nullptr, context);
81-
ASSERT_EQ(ret, UR_RESULT_SUCCESS);
82-
poolDescriptors = std::move(descs);
90+
auto &testDevices = uur::DevicesEnvironment::instance->devices;
91+
auto devices = collectDeviceHandles(testDevices);
92+
poolDescriptors = usm::pool_descriptor::createFromDevices(
93+
nullptr, this->context, devices);
8394
}
8495

8596
std::vector<usm::pool_descriptor> poolDescriptors;

0 commit comments

Comments
 (0)