Skip to content

Commit 7e50ca5

Browse files
lslusarczykldorau
authored andcommitted
[UR][L0] Memory resident limit to enabled peers
Co-authored-by: Łukasz Ślusarczyk <lukasz.slusarczyk@intel.com> Co-authored-by: Lukasz Dorau <lukasz.dorau@intel.com> Signed-off-by: Lukasz Dorau <lukasz.dorau@intel.com>
1 parent 929fd90 commit 7e50ca5

17 files changed

Lines changed: 441 additions & 109 deletions

File tree

sycl/source/device.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -212,19 +212,33 @@ bool device::has(aspect Aspect) const { return impl->has(Aspect); }
212212
void device::ext_oneapi_enable_peer_access(const device &peer) {
213213
ur_device_handle_t Device = impl->getHandleRef();
214214
ur_device_handle_t Peer = peer.impl->getHandleRef();
215-
if (Device != Peer) {
216-
detail::adapter_impl &Adapter = impl->getAdapter();
217-
Adapter.call<detail::UrApiKind::urUsmP2PEnablePeerAccessExp>(Device, Peer);
215+
216+
if (Device == Peer)
217+
return;
218+
219+
if (peer.get_platform() != get_platform()) {
220+
throw exception(errc::invalid,
221+
"Can not enable peer access between different platforms");
218222
}
223+
224+
impl->getAdapter().call<detail::UrApiKind::urUsmP2PEnablePeerAccessExp>(
225+
Device, Peer);
219226
}
220227

221228
void device::ext_oneapi_disable_peer_access(const device &peer) {
222229
ur_device_handle_t Device = impl->getHandleRef();
223230
ur_device_handle_t Peer = peer.impl->getHandleRef();
224-
if (Device != Peer) {
225-
detail::adapter_impl &Adapter = impl->getAdapter();
226-
Adapter.call<detail::UrApiKind::urUsmP2PDisablePeerAccessExp>(Device, Peer);
231+
232+
if (Device == Peer)
233+
return;
234+
235+
if (peer.get_platform() != get_platform()) {
236+
throw exception(errc::invalid,
237+
"Can not disable peer access between different platforms");
227238
}
239+
240+
impl->getAdapter().call<detail::UrApiKind::urUsmP2PDisablePeerAccessExp>(
241+
Device, Peer);
228242
}
229243

230244
bool device::ext_oneapi_can_access_peer(const device &peer,

unified-runtime/source/adapters/level_zero/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@ if(UR_BUILD_ADAPTER_L0_V2)
150150
${CMAKE_CURRENT_SOURCE_DIR}/helpers/kernel_helpers.cpp
151151
${CMAKE_CURRENT_SOURCE_DIR}/helpers/memory_helpers.cpp
152152
${CMAKE_CURRENT_SOURCE_DIR}/helpers/mutable_helpers.cpp
153-
${CMAKE_CURRENT_SOURCE_DIR}/usm_p2p.cpp
154153
${CMAKE_CURRENT_SOURCE_DIR}/virtual_mem.cpp
155154
${CMAKE_CURRENT_SOURCE_DIR}/../../ur/ur.cpp
156155
${CMAKE_CURRENT_SOURCE_DIR}/sampler.hpp
@@ -194,6 +193,7 @@ if(UR_BUILD_ADAPTER_L0_V2)
194193
${CMAKE_CURRENT_SOURCE_DIR}/v2/queue_immediate_in_order.cpp
195194
${CMAKE_CURRENT_SOURCE_DIR}/v2/queue_immediate_out_of_order.cpp
196195
${CMAKE_CURRENT_SOURCE_DIR}/v2/usm.cpp
196+
${CMAKE_CURRENT_SOURCE_DIR}/v2/usm_p2p.cpp
197197
)
198198
install_ur_library(ur_adapter_level_zero_v2)
199199

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ ur_result_t urContextCreate(
4141

4242
Context->initialize();
4343
*RetContext = reinterpret_cast<ur_context_handle_t>(Context);
44+
// TODO: delete below 'if' when memory isolation in the context is
45+
// implemented in the driver
4446
if (IndirectAccessTrackingEnabled) {
4547
std::scoped_lock<ur_shared_mutex> Lock(Platform->ContextsMutex);
4648
Platform->Contexts.push_back(*RetContext);

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2353,3 +2353,24 @@ void ZeUSMImportExtension::doZeUSMRelease(ze_driver_handle_t DriverHandle,
23532353
void *HostPtr) {
23542354
ZE_CALL_NOCHECK(zexDriverReleaseImportedPointer, (DriverHandle, HostPtr));
23552355
}
2356+
2357+
std::ostream &operator<<(std::ostream &os,
2358+
ur_device_handle_t_ const &device_handle) {
2359+
if (device_handle.Id.has_value()) {
2360+
return os << device_handle.Id.value();
2361+
}
2362+
return os << "NONE";
2363+
}
2364+
2365+
std::ostream &operator<<(std::ostream &os,
2366+
ur_device_handle_t_::PeerStatus peer_status) {
2367+
switch (peer_status) {
2368+
case ur_device_handle_t_::PeerStatus::DISABLED:
2369+
return os << "DISABLED";
2370+
case ur_device_handle_t_::PeerStatus::ENABLED:
2371+
return os << "ENABLED";
2372+
case ur_device_handle_t_::PeerStatus::NO_CONNECTION:
2373+
return os << "NO_CONNECTION";
2374+
}
2375+
return os << "UNKNOWN";
2376+
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,17 +261,29 @@ struct ur_device_handle_t_ : ur_object {
261261
std::unordered_map<ur_exp_image_native_handle_t, ze_image_handle_t>
262262
ZeOffsetToImageHandleMap;
263263

264+
// Devices which user enabled p2p access by
265+
// urUsmP2P(Enable|Disable)PeerAccessExp. Devices are indexed by device id.
266+
enum class PeerStatus : char { ENABLED, DISABLED, NO_CONNECTION };
267+
std::vector<PeerStatus>
268+
peers; // info if our device can access given peer device allocations
269+
264270
// unique ephemeral identifer of the device in the adapter
265271
std::optional<DeviceId> Id;
266272

267273
ur::RefCount RefCount;
268274
};
269275

276+
std::ostream &operator<<(std::ostream &os,
277+
ur_device_handle_t_ const &device_handle);
278+
std::ostream &operator<<(std::ostream &os,
279+
ur_device_handle_t_::PeerStatus peer_status);
280+
270281
// Collects a flat vector of unique devices for USM memory pool creation.
271282
// Traverses the input devices and their sub-devices, ensuring each Level Zero
272283
// device handle appears only once in the result.
273284
inline std::vector<ur_device_handle_t> CollectDevicesForUsmPoolCreation(
274285
const std::vector<ur_device_handle_t> &Devices) {
286+
275287
std::vector<ur_device_handle_t> DevicesAndSubDevices;
276288
std::unordered_set<ze_device_handle_t> Seen;
277289

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

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -746,9 +746,9 @@ ur_platform_handle_t_::getDeviceFromNativeHandle(ze_device_handle_t ZeDevice) {
746746
std::shared_lock<ur_shared_mutex> Lock(URDevicesCacheMutex);
747747
auto it = std::find_if(URDevicesCache.begin(), URDevicesCache.end(),
748748
[&](std::unique_ptr<ur_device_handle_t_> &D) {
749-
return D.get()->ZeDevice == ZeDevice &&
750-
(D.get()->RootDevice == nullptr ||
751-
D.get()->RootDevice->RootDevice == nullptr);
749+
return D->ZeDevice == ZeDevice &&
750+
(D->RootDevice == nullptr ||
751+
D->RootDevice->RootDevice == nullptr);
752752
});
753753
if (it != URDevicesCache.end()) {
754754
return (*it).get();
@@ -914,6 +914,44 @@ ur_result_t ur_platform_handle_t_::populateDeviceCacheIfNeeded() {
914914
ZeDeviceSynchronizeSupported = Supported;
915915
}
916916

917+
for (auto &dev : URDevicesCache) {
918+
dev->peers = std::vector<ur_device_handle_t_::PeerStatus>(
919+
URDevicesCache.size(), ur_device_handle_t_::PeerStatus::NO_CONNECTION);
920+
921+
for (size_t peerId = 0; peerId < URDevicesCache.size(); ++peerId) {
922+
if (peerId == dev->Id.value())
923+
continue;
924+
925+
ZeStruct<ze_device_p2p_properties_t> p2pProperties;
926+
ZE2UR_CALL_THROWS(
927+
zeDeviceGetP2PProperties,
928+
(dev->ZeDevice, URDevicesCache[peerId]->ZeDevice, &p2pProperties));
929+
if (!(p2pProperties.flags & ZE_DEVICE_P2P_PROPERTY_FLAG_ACCESS)) {
930+
UR_LOG(INFO,
931+
"p2p access to memory of dev:{} from dev:{} not possible due to "
932+
"lack of p2p property",
933+
peerId, dev->Id.value());
934+
continue;
935+
}
936+
937+
ze_bool_t p2p;
938+
ZE2UR_CALL_THROWS(
939+
zeDeviceCanAccessPeer,
940+
(dev->ZeDevice, URDevicesCache[peerId]->ZeDevice, &p2p));
941+
if (!p2p) {
942+
UR_LOG(INFO,
943+
"p2p access to memory of dev:{} from dev:{} not possible due to "
944+
"no connection",
945+
peerId, dev->Id.value());
946+
continue;
947+
}
948+
949+
UR_LOG(INFO, "p2p access to memory of dev:{} from dev:{} can be enabled",
950+
peerId, dev->Id.value());
951+
dev->peers[peerId] = ur_device_handle_t_::PeerStatus::DISABLED;
952+
}
953+
}
954+
917955
return UR_RESULT_SUCCESS;
918956
}
919957

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,10 @@ struct ur_platform_handle_t_ : ur::handle_base<ur::level_zero::ddi_getter>,
9797
uint32_t VersionMinor,
9898
uint32_t VersionBuild);
9999

100-
// Keep track of all contexts in the platform. This is needed to manage
101-
// a lifetime of memory allocations in each context when there are kernels
102-
// with indirect access.
103-
// TODO: should be deleted when memory isolation in the context is implemented
104-
// in the driver.
100+
// Keep track of all contexts in the platform. In v1 L0 this is needed to
101+
// manage a lifetime of memory allocations in each context when there are
102+
// kernels with indirect access. In v2 it is used during
103+
// ext_oneapi_enable_peer_access and ext_oneapi_disable_peer_access calls.
105104
std::list<ur_context_handle_t> Contexts;
106105
ur_shared_mutex ContextsMutex;
107106

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,23 @@
1212

1313
namespace ur::level_zero {
1414

15-
ur_result_t urUsmP2PEnablePeerAccessExp(ur_device_handle_t /*commandDevice*/,
16-
ur_device_handle_t /*peerDevice*/) {
15+
ur_result_t urUsmP2PEnablePeerAccessExp(ur_device_handle_t commandDevice,
16+
ur_device_handle_t peerDevice) {
1717

18-
// L0 has peer devices enabled by default
18+
UR_LOG(INFO,
19+
"user enables peer access to memory of {} from {}, ignored, in V1 P2P "
20+
"is always enabled",
21+
*commandDevice, *peerDevice);
1922
return UR_RESULT_SUCCESS;
2023
}
2124

22-
ur_result_t urUsmP2PDisablePeerAccessExp(ur_device_handle_t /*commandDevice*/,
23-
ur_device_handle_t /*peerDevice*/) {
25+
ur_result_t urUsmP2PDisablePeerAccessExp(ur_device_handle_t commandDevice,
26+
ur_device_handle_t peerDevice) {
2427

25-
// L0 has peer devices enabled by default
28+
UR_LOG(INFO,
29+
"user disables peer access to memory of {} from {}, ignored, in V1 "
30+
"P2P is always enabled",
31+
*commandDevice, *peerDevice);
2632
return UR_RESULT_SUCCESS;
2733
}
2834

0 commit comments

Comments
 (0)