Skip to content

Commit 74dab57

Browse files
committed
Implement dpctl.SyclDevice peer access
1 parent fa4eaa7 commit 74dab57

File tree

7 files changed

+264
-0
lines changed

7 files changed

+264
-0
lines changed

dpctl/_backend.pxd

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ cdef extern from "syclinterface/dpctl_sycl_enum_types.h":
112112
_L1_cache "L1_cache",
113113
_next_partitionable "next_partitionable",
114114

115+
ctypedef enum _peer_access "DPCTLPeerAccessType":
116+
_access_supported "access_supported",
117+
_atomics_supported "atomics_supported",
118+
115119
ctypedef enum _event_status_type "DPCTLSyclEventStatusType":
116120
_UNKNOWN_STATUS "DPCTL_UNKNOWN_STATUS"
117121
_SUBMITTED "DPCTL_SUBMITTED"
@@ -278,7 +282,14 @@ cdef extern from "syclinterface/dpctl_sycl_device_interface.h":
278282
cdef DPCTLDeviceVectorRef DPCTLDevice_GetComponentDevices(
279283
const DPCTLSyclDeviceRef DRef
280284
)
285+
cdef bool DPCTLDevice_CanAccessPeer(const DPCTLSyclDeviceRef DRef,
286+
const DPCTLSyclDeviceRef PDRef,
287+
_peer_access PT)
288+
cdef void DPCTLDevice_EnablePeerAccess(const DPCTLSyclDeviceRef DRef,
289+
const DPCTLSyclDeviceRef PDRef)
281290

291+
cdef void DPCTLDevice_DisablePeerAccess(const DPCTLSyclDeviceRef DRef,
292+
const DPCTLSyclDeviceRef PDRef)
282293

283294
cdef extern from "syclinterface/dpctl_sycl_device_manager.h":
284295
cdef DPCTLDeviceVectorRef DPCTLDeviceVector_CreateFromArray(

dpctl/_sycl_device.pyx

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,15 @@ from ._backend cimport ( # noqa: E211
2525
DPCTLCString_Delete,
2626
DPCTLDefaultSelector_Create,
2727
DPCTLDevice_AreEq,
28+
DPCTLDevice_CanAccessPeer,
2829
DPCTLDevice_Copy,
2930
DPCTLDevice_CreateFromSelector,
3031
DPCTLDevice_CreateSubDevicesByAffinity,
3132
DPCTLDevice_CreateSubDevicesByCounts,
3233
DPCTLDevice_CreateSubDevicesEqually,
3334
DPCTLDevice_Delete,
35+
DPCTLDevice_DisablePeerAccess,
36+
DPCTLDevice_EnablePeerAccess,
3437
DPCTLDevice_GetBackend,
3538
DPCTLDevice_GetComponentDevices,
3639
DPCTLDevice_GetCompositeDevice,
@@ -103,6 +106,7 @@ from ._backend cimport ( # noqa: E211
103106
_device_type,
104107
_global_mem_cache_type,
105108
_partition_affinity_domain_type,
109+
_peer_access,
106110
)
107111

108112
from .enum_types import backend_type, device_type, global_mem_cache_type
@@ -1792,6 +1796,108 @@ cdef class SyclDevice(_SyclDevice):
17921796
raise ValueError("Internal error: NULL device vector encountered")
17931797
return _get_devices(cDVRef)
17941798

1799+
def can_access_peer(self, peer):
1800+
""" Returns ``True`` if `self` can enable peer access
1801+
to `peer`, ``False`` otherwise.
1802+
1803+
Args:
1804+
peer (dpctl.SyclDevice):
1805+
The :class:`dpctl.SyclDevice` instance to
1806+
check.
1807+
1808+
Returns:
1809+
bool:
1810+
``True`` if `self` can enable peer access
1811+
to `peer`, otherwise ``False``.
1812+
"""
1813+
cdef SyclDevice p_dev
1814+
if not isinstance(peer, SyclDevice):
1815+
raise TypeError(
1816+
"second argument must be a `dpctl.SyclDevice`, got "
1817+
f"{type(peer)}"
1818+
)
1819+
p_dev = <SyclDevice>peer
1820+
return DPCTLDevice_CanAccessPeer(
1821+
self._device_ref,
1822+
p_dev.get_device_ref(),
1823+
_peer_access._access_supported
1824+
)
1825+
1826+
def can_access_peer_atomics_supported(self, peer):
1827+
""" Returns ``True`` if `self` can enable peer access
1828+
to and can atomically modify memory on `peer`, ``False`` otherwise.
1829+
1830+
Args:
1831+
peer (dpctl.SyclDevice):
1832+
The :class:`dpctl.SyclDevice` instance to
1833+
check.
1834+
1835+
Returns:
1836+
bool:
1837+
``True`` if `self` can enable peer access
1838+
to and can atomically modify memory on `peer`,
1839+
otherwise ``False``.
1840+
"""
1841+
cdef SyclDevice p_dev
1842+
if not isinstance(peer, SyclDevice):
1843+
raise TypeError(
1844+
"second argument must be a `dpctl.SyclDevice`, got "
1845+
f"{type(peer)}"
1846+
)
1847+
p_dev = <SyclDevice>peer
1848+
return DPCTLDevice_CanAccessPeer(
1849+
self._device_ref,
1850+
p_dev.get_device_ref(),
1851+
_peer_access._atomics_supported
1852+
)
1853+
1854+
def enable_peer_access(self, peer):
1855+
""" Enables this device (`self`) to access USM device allocations
1856+
located on `peer`.
1857+
1858+
Args:
1859+
peer (dpctl.SyclDevice):
1860+
The :class:`dpctl.SyclDevice` instance to
1861+
enable peer access to.
1862+
1863+
Raises:
1864+
ValueError:
1865+
If the ``DPCTLDevice_GetComponentDevices`` call returned
1866+
``NULL`` instead of a ``DPCTLDeviceVectorRef`` object.
1867+
"""
1868+
cdef SyclDevice p_dev
1869+
if not isinstance(peer, SyclDevice):
1870+
raise TypeError(
1871+
"second argument must be a `dpctl.SyclDevice`, got "
1872+
f"{type(peer)}"
1873+
)
1874+
p_dev = <SyclDevice>peer
1875+
DPCTLDevice_EnablePeerAccess(self._device_ref, p_dev.get_device_ref())
1876+
return
1877+
1878+
def disable_peer_access(self, peer):
1879+
""" Disables peer access to `peer` from `self`.
1880+
1881+
Args:
1882+
peer (dpctl.SyclDevice):
1883+
The :class:`dpctl.SyclDevice` instance to
1884+
disable peer access to.
1885+
1886+
Raises:
1887+
ValueError:
1888+
If the ``DPCTLDevice_GetComponentDevices`` call returned
1889+
``NULL`` instead of a ``DPCTLDeviceVectorRef`` object.
1890+
"""
1891+
cdef SyclDevice p_dev
1892+
if not isinstance(peer, SyclDevice):
1893+
raise TypeError(
1894+
"second argument must be a `dpctl.SyclDevice`, got "
1895+
f"{type(peer)}"
1896+
)
1897+
p_dev = <SyclDevice>peer
1898+
DPCTLDevice_DisablePeerAccess(self._device_ref, p_dev.get_device_ref())
1899+
return
1900+
17951901
@property
17961902
def profiling_timer_resolution(self):
17971903
""" Profiling timer resolution.

libsyclinterface/helper/include/dpctl_utils_helper.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,33 @@ DPCTL_API
179179
DPCTLPartitionAffinityDomainType DPCTL_SyclPartitionAffinityDomainToDPCTLType(
180180
sycl::info::partition_affinity_domain PartitionAffinityDomain);
181181

182+
/*!
183+
* @brief Converts a DPCTLPeerAccessType enum value to its corresponding
184+
* sycl::ext::oneapi::peer_access enum value.
185+
*
186+
* @param PeerAccessTy A DPCTLPeerAccessType enum value
187+
* @return A sycl::ext::oneapi::peer_access enum value for the input
188+
* DPCTLPeerAccessType enum value.
189+
* @throws runtime_error
190+
*/
191+
DPCTL_API
192+
sycl::ext::oneapi::peer_access
193+
DPCTL_DPCTLPeerAccessTypeToSycl(DPCTLPeerAccessType PeerAccessTy);
194+
195+
/*!
196+
* @brief Converts a sycl::ext::oneapi::peer_access enum value to
197+
* corresponding DPCTLPeerAccessType enum value.
198+
*
199+
* @param PeerAccess sycl::ext::oneapi::peer_access to be
200+
* converted to DPCTLPeerAccessType enum.
201+
* @return A DPCTLPeerAccessType enum value for the input
202+
* sycl::ext::oneapi::peer_access enum value.
203+
* @throws runtime_error
204+
*/
205+
DPCTL_API
206+
DPCTLPeerAccessType
207+
DPCTL_SyclPeerAccessToDPCTLType(sycl::ext::oneapi::peer_access PeerAccess);
208+
182209
/*!
183210
* @brief Gives the index of the given device with respective to all the other
184211
* devices of the same type in the device's platform.

libsyclinterface/helper/source/dpctl_utils_helper.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,32 @@ DPCTLPartitionAffinityDomainType DPCTL_SyclPartitionAffinityDomainToDPCTLType(
452452
}
453453
}
454454

455+
ext::oneapi::peer_access
456+
DPCTL_DPCTLPeerAccessTypeToSycl(DPCTLPeerAccessType PeerAccessTy)
457+
{
458+
switch (PeerAccessTy) {
459+
case DPCTLPeerAccessType::access_supported:
460+
return ext::oneapi::peer_access::access_supported;
461+
case DPCTLPeerAccessType::atomics_supported:
462+
return ext::oneapi::peer_access::atomics_supported;
463+
default:
464+
throw std::runtime_error("Unsupported peer_access type");
465+
}
466+
}
467+
468+
DPCTLPeerAccessType
469+
DPCTL_SyclPeerAccessToDPCTLType(ext::oneapi::peer_access PeerAccess)
470+
{
471+
switch (PeerAccess) {
472+
case ext::oneapi::peer_access::access_supported:
473+
return DPCTLPeerAccessType::access_supported;
474+
case ext::oneapi::peer_access::atomics_supported:
475+
return DPCTLPeerAccessType::atomics_supported;
476+
default:
477+
throw std::runtime_error("Unsupported peer_access type");
478+
}
479+
}
480+
455481
int64_t DPCTL_GetRelativeDeviceId(const device &Device)
456482
{
457483
auto relid = -1;

libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,4 +792,40 @@ DPCTL_API
792792
__dpctl_give DPCTLDeviceVectorRef
793793
DPCTLDevice_GetComponentDevices(__dpctl_keep const DPCTLSyclDeviceRef DRef);
794794

795+
/*!
796+
* @brief Checks if device supports peer access to another device.
797+
*
798+
* @param DRef Opaque pointer to a ``sycl::device``
799+
* @param PDRef Opaque pointer to a ``sycl::device``
800+
* @param PT DPCTLPeerAccessType of ``ext::oneapi::peer_access``.
801+
* @return True if sycl::device supports the kind of peer access, else false.
802+
* @ingroup DeviceInterface
803+
*/
804+
DPCTL_API
805+
bool DPCTLDevice_CanAccessPeer(__dpctl_keep const DPCTLSyclDeviceRef DRef,
806+
__dpctl_keep const DPCTLSyclDeviceRef PDRef,
807+
DPCTLPeerAccessType PT);
808+
809+
/*!
810+
* @brief Checks if device supports peer access to another device.
811+
*
812+
* @param DRef Opaque pointer to a ``sycl::device``
813+
* @param PDRef Opaque pointer to a ``sycl::device``
814+
* @ingroup DeviceInterface
815+
*/
816+
DPCTL_API
817+
void DPCTLDevice_EnablePeerAccess(__dpctl_keep const DPCTLSyclDeviceRef DRef,
818+
__dpctl_keep const DPCTLSyclDeviceRef PDRef);
819+
820+
/*!
821+
* @brief Checks if device supports peer access to another device.
822+
*
823+
* @param DRef Opaque pointer to a ``sycl::device``
824+
* @param PDRef Opaque pointer to a ``sycl::device``
825+
* @ingroup DeviceInterface
826+
*/
827+
DPCTL_API
828+
void DPCTLDevice_DisablePeerAccess(__dpctl_keep const DPCTLSyclDeviceRef DRef,
829+
__dpctl_keep const DPCTLSyclDeviceRef PDRef);
830+
795831
DPCTL_C_EXTERN_C_END

libsyclinterface/include/syclinterface/dpctl_sycl_enum_types.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,16 @@ typedef enum
151151
next_partitionable
152152
} DPCTLPartitionAffinityDomainType;
153153

154+
/*!
155+
* @brief DPCTL analogue of ``sycl::ext::oneapi::peer_access`` enum.
156+
*
157+
*/
158+
typedef enum
159+
{
160+
access_supported,
161+
atomics_supported
162+
} DPCTLPeerAccessType;
163+
154164
/*!
155165
* @brief Enums to depict the properties that can be passed to a sycl::queue
156166
* constructor.

libsyclinterface/source/dpctl_sycl_device_interface.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,3 +903,51 @@ DPCTLDevice_GetCompositeDevice(__dpctl_keep const DPCTLSyclDeviceRef DRef)
903903
else
904904
return nullptr;
905905
}
906+
907+
bool DPCTLDevice_CanAccessPeer(__dpctl_keep const DPCTLSyclDeviceRef DRef,
908+
__dpctl_keep const DPCTLSyclDeviceRef PDRef,
909+
DPCTLPeerAccessType PT)
910+
{
911+
bool canAccess = false;
912+
auto D = unwrap<device>(DRef);
913+
auto PD = unwrap<device>(PDRef);
914+
if (D && PD) {
915+
try {
916+
canAccess = D->ext_oneapi_can_access_peer(
917+
*PD, DPCTL_DPCTLPeerAccessTypeToSycl(PT));
918+
} catch (std::exception const &e) {
919+
error_handler(e, __FILE__, __func__, __LINE__);
920+
}
921+
}
922+
return canAccess;
923+
}
924+
925+
void DPCTLDevice_EnablePeerAccess(__dpctl_keep const DPCTLSyclDeviceRef DRef,
926+
__dpctl_keep const DPCTLSyclDeviceRef PDRef)
927+
{
928+
auto D = unwrap<device>(DRef);
929+
auto PD = unwrap<device>(PDRef);
930+
if (D && PD) {
931+
try {
932+
D->ext_oneapi_enable_peer_access(*PD);
933+
} catch (std::exception const &e) {
934+
error_handler(e, __FILE__, __func__, __LINE__);
935+
}
936+
}
937+
return;
938+
}
939+
940+
void DPCTLDevice_DisablePeerAccess(__dpctl_keep const DPCTLSyclDeviceRef DRef,
941+
__dpctl_keep const DPCTLSyclDeviceRef PDRef)
942+
{
943+
auto D = unwrap<device>(DRef);
944+
auto PD = unwrap<device>(PDRef);
945+
if (D && PD) {
946+
try {
947+
D->ext_oneapi_disable_peer_access(*PD);
948+
} catch (std::exception const &e) {
949+
error_handler(e, __FILE__, __func__, __LINE__);
950+
}
951+
}
952+
return;
953+
}

0 commit comments

Comments
 (0)