Skip to content

Commit 94af6e3

Browse files
authored
Merge pull request #1369 from JackAKirk/usm-p2p-add-test-and-macro
[EXP][usm p2p] Add test for ur_exp_usm_p2p and impl for hip
2 parents 6513abc + ad198f9 commit 94af6e3

13 files changed

+152
-25
lines changed

include/ur_api.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8927,6 +8927,13 @@ urUSMReleaseExp(
89278927
#if !defined(__GNUC__)
89288928
#pragma region usm p2p(experimental)
89298929
#endif
8930+
///////////////////////////////////////////////////////////////////////////////
8931+
#ifndef UR_USM_P2P_EXTENSION_STRING_EXP
8932+
/// @brief The extension string that defines support for USM P2P which is
8933+
/// returned when querying device extensions.
8934+
#define UR_USM_P2P_EXTENSION_STRING_EXP "ur_exp_usm_p2p"
8935+
#endif // UR_USM_P2P_EXTENSION_STRING_EXP
8936+
89308937
///////////////////////////////////////////////////////////////////////////////
89318938
/// @brief Supported peer info
89328939
typedef enum ur_exp_peer_info_t {

scripts/core/EXP-USM-P2P.rst

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,20 @@ or copying the memory located on a separate "peer" device.
2727

2828
Motivation
2929
--------------------------------------------------------------------------------
30-
Several important projects that the SYCL programming model aims to support use
31-
fine-grained peer to peer memory access controls.
32-
Two such examples that SYCL supports are Pytorch and Gromacs.
33-
This experimental extension to UR aims to provide a portable interface that can
34-
call appropriate driver functions to query and control peer memory access
35-
across the CUDA, HIP and L0 adapters.
30+
Programming models like SYCL or OpenMP aim to support several important
31+
projects that utilise fine-grained peer-to-peer memory access controls.
32+
This experimental extension to the Unified-Runtime API aims to provide a
33+
portable interface that can call appropriate driver functions to query and
34+
control peer memory access within different adapters such as CUDA, HIP and
35+
Level Zero.
3636

3737
API
3838
--------------------------------------------------------------------------------
3939

40+
Macros
41+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42+
* ${X}_USM_P2P_EXTENSION_STRING_EXP
43+
4044
Enums
4145
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4246

@@ -48,14 +52,23 @@ Functions
4852
* ${x}UsmP2PDisablePeerAccessExp
4953
* ${x}UsmP2PPeerAccessGetInfoExp
5054

55+
Support
56+
--------------------------------------------------------------------------------
57+
58+
Adapters which support this experimental feature *must* return the valid string
59+
defined in ``${X}_USM_P2P_EXTENSION_STRING_EXP`` as one of the options from
60+
${x}DeviceGetInfo when querying for ${X}_DEVICE_INFO_EXTENSIONS.
61+
5162
Changelog
5263
--------------------------------------------------------------------------------
5364

54-
+-----------+------------------------+
55-
| Revision | Changes |
56-
+===========+========================+
57-
| 1.0 | Initial Draft |
58-
+-----------+------------------------+
65+
+-----------+---------------------------------------------+
66+
| Revision | Changes |
67+
+===========+=============================================+
68+
| 1.0 | Initial Draft |
69+
+-----------+---------------------------------------------+
70+
| 1.1 | Added USM_P2P_EXTENSION_STRING_EXP ID Macro |
71+
+-----------+---------------------------------------------+
5972

6073
Contributors
6174
--------------------------------------------------------------------------------

scripts/core/exp-usm-p2p.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ type: header
1212
desc: "Intel $OneApi Unified Runtime Experimental APIs for USM P2P"
1313
ordinal: "99"
1414
--- #--------------------------------------------------------------------------
15+
type: macro
16+
desc: "The extension string that defines support for USM P2P which is returned when querying device extensions."
17+
name: $X_USM_P2P_EXTENSION_STRING_EXP
18+
value: "\"$x_exp_usm_p2p\""
19+
--- #--------------------------------------------------------------------------
1520
type: enum
1621
desc: "Supported peer info"
1722
class: $xUsmP2P

source/adapters/cuda/device.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,7 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice,
612612
SupportedExtensions += "pi_ext_intel_devicelib_assert ";
613613
// Return supported for the UR command-buffer experimental feature
614614
SupportedExtensions += "ur_exp_command_buffer ";
615+
SupportedExtensions += "ur_exp_usm_p2p ";
615616
SupportedExtensions += " ";
616617

617618
int Major = 0;

source/adapters/hip/usm_p2p.cpp

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,57 @@
99
//===----------------------------------------------------------------------===//
1010

1111
#include "common.hpp"
12+
#include "context.hpp"
1213

13-
UR_APIEXPORT ur_result_t UR_APICALL
14-
urUsmP2PEnablePeerAccessExp(ur_device_handle_t, ur_device_handle_t) {
15-
detail::ur::die(
16-
"urUsmP2PEnablePeerAccessExp is not implemented for HIP adapter.");
17-
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
14+
UR_APIEXPORT ur_result_t UR_APICALL urUsmP2PEnablePeerAccessExp(
15+
ur_device_handle_t commandDevice, ur_device_handle_t peerDevice) {
16+
try {
17+
ScopedContext active(commandDevice);
18+
UR_CHECK_ERROR(hipDeviceEnablePeerAccess(peerDevice->get(), 0));
19+
} catch (ur_result_t err) {
20+
return err;
21+
}
22+
return UR_RESULT_SUCCESS;
1823
}
1924

20-
UR_APIEXPORT ur_result_t UR_APICALL
21-
urUsmP2PDisablePeerAccessExp(ur_device_handle_t, ur_device_handle_t) {
22-
detail::ur::die(
23-
"urUsmP2PDisablePeerAccessExp is not implemented for HIP adapter.");
24-
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
25+
UR_APIEXPORT ur_result_t UR_APICALL urUsmP2PDisablePeerAccessExp(
26+
ur_device_handle_t commandDevice, ur_device_handle_t peerDevice) {
27+
try {
28+
ScopedContext active(commandDevice);
29+
UR_CHECK_ERROR(hipDeviceDisablePeerAccess(peerDevice->get()));
30+
} catch (ur_result_t err) {
31+
return err;
32+
}
33+
return UR_RESULT_SUCCESS;
2534
}
2635

2736
UR_APIEXPORT ur_result_t UR_APICALL urUsmP2PPeerAccessGetInfoExp(
28-
ur_device_handle_t, ur_device_handle_t, ur_exp_peer_info_t, size_t propSize,
29-
void *pPropValue, size_t *pPropSizeRet) {
37+
ur_device_handle_t commandDevice, ur_device_handle_t peerDevice,
38+
ur_exp_peer_info_t propName, size_t propSize, void *pPropValue,
39+
size_t *pPropSizeRet) {
3040
UrReturnHelper ReturnValue(propSize, pPropValue, pPropSizeRet);
31-
// Zero return value indicates that all of the queries currently return false.
32-
return ReturnValue(uint32_t{0});
41+
42+
int value;
43+
hipDeviceP2PAttr hipAttr;
44+
try {
45+
ScopedContext active(commandDevice);
46+
switch (propName) {
47+
case UR_EXP_PEER_INFO_UR_PEER_ACCESS_SUPPORTED: {
48+
hipAttr = hipDevP2PAttrAccessSupported;
49+
break;
50+
}
51+
case UR_EXP_PEER_INFO_UR_PEER_ATOMICS_SUPPORTED: {
52+
hipAttr = hipDevP2PAttrNativeAtomicSupported;
53+
break;
54+
}
55+
default: {
56+
return UR_RESULT_ERROR_INVALID_ENUMERATION;
57+
}
58+
}
59+
UR_CHECK_ERROR(hipDeviceGetP2PAttribute(
60+
&value, hipAttr, commandDevice->get(), peerDevice->get()));
61+
} catch (ur_result_t err) {
62+
return err;
63+
}
64+
return ReturnValue(value);
3365
}

test/conformance/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ if(UR_DPCXX)
120120
add_subdirectory(program)
121121
add_subdirectory(enqueue)
122122
add_subdirectory(exp_command_buffer)
123+
add_subdirectory(exp_usm_p2p)
123124
else()
124125
message(WARNING
125126
"UR_DPCXX is not defined, the following conformance test executables \
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (C) 2024 Intel Corporation
2+
# Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
3+
# See LICENSE.TXT
4+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
6+
add_conformance_test_with_devices_environment(exp_usm_p2p
7+
usm_p2p.cpp
8+
)

test/conformance/exp_usm_p2p/exp_usm_p2p_adapter_cuda.match

Whitespace-only changes.

test/conformance/exp_usm_p2p/exp_usm_p2p_adapter_hip.match

Whitespace-only changes.

test/conformance/exp_usm_p2p/exp_usm_p2p_adapter_level_zero.match

Whitespace-only changes.

test/conformance/exp_usm_p2p/exp_usm_p2p_adapter_native_cpu.match

Whitespace-only changes.

test/conformance/exp_usm_p2p/exp_usm_p2p_adapter_opencl.match

Whitespace-only changes.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright (C) 2024 Intel Corporation
2+
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
3+
// Exceptions. See LICENSE.TXT
4+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
6+
#include "uur/fixtures.h"
7+
#include "uur/raii.h"
8+
9+
using urP2PTest = uur::urAllDevicesTest;
10+
11+
TEST_F(urP2PTest, Success) {
12+
13+
if (devices.size() < 2) {
14+
GTEST_SKIP();
15+
}
16+
17+
size_t returned_size;
18+
ASSERT_SUCCESS(urDeviceGetInfo(devices[0], UR_DEVICE_INFO_EXTENSIONS, 0,
19+
nullptr, &returned_size));
20+
21+
std::unique_ptr<char[]> returned_extensions(new char[returned_size]);
22+
23+
ASSERT_SUCCESS(urDeviceGetInfo(devices[0], UR_DEVICE_INFO_EXTENSIONS,
24+
returned_size, returned_extensions.get(),
25+
nullptr));
26+
27+
std::string_view extensions_string(returned_extensions.get());
28+
const bool usm_p2p_support =
29+
extensions_string.find(UR_USM_P2P_EXTENSION_STRING_EXP) !=
30+
std::string::npos;
31+
32+
if (!usm_p2p_support) {
33+
GTEST_SKIP() << "EXP usm p2p feature is not supported.";
34+
}
35+
36+
int value;
37+
ASSERT_SUCCESS(urUsmP2PPeerAccessGetInfoExp(
38+
devices[0], ///< [in] handle of the command device object
39+
devices[1], ///< [in] handle of the peer device object
40+
UR_EXP_PEER_INFO_UR_PEER_ACCESS_SUPPORTED, sizeof(int), &value,
41+
&returned_size));
42+
// Note that whilst it is not currently specified to be a requirement in the
43+
// specification, currently all supported backends return value = 1 for the
44+
// UR_EXP_PEER_INFO_UR_PEER_ACCESS_SUPPORTED query when the query is true
45+
// (matching the native query return values). Generally different backends can
46+
// return different values for a given device query; however it is
47+
// advisable that for boolean queries they return the same values to indicate
48+
// true/false. When this extension is moved out of experimental status such
49+
// boolean return values should be specified by the extension.
50+
ASSERT_EQ(value, 1);
51+
52+
// Just check that this doesn't throw since supporting peer atomics is
53+
// optional and can depend on backend/device.
54+
ASSERT_SUCCESS(urUsmP2PPeerAccessGetInfoExp(
55+
devices[0], devices[1], UR_EXP_PEER_INFO_UR_PEER_ATOMICS_SUPPORTED,
56+
sizeof(int), &value, &returned_size));
57+
58+
ASSERT_SUCCESS(urUsmP2PEnablePeerAccessExp(devices[0], devices[1]));
59+
ASSERT_SUCCESS(urUsmP2PDisablePeerAccessExp(devices[0], devices[1]));
60+
}

0 commit comments

Comments
 (0)