From 76637ae288e816b2a4f3a0f5e68bb0fec626dda7 Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Thu, 16 Mar 2023 11:57:04 -0500 Subject: [PATCH 1/2] Used functools.cache to cache filter_string property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed docstring of filter_string property. Introduced internal dpctl._sycl_device._cached_filter_string stand-alone function that is decorated with functools.cache Used that internal function in implementation of dpctl.SyclDevice.filter_string. Caching improved timing of filter_string property: ``` In [1]: import dpctl In [2]: d = dpctl.SyclDevice() In [3]: %timeit d.filter_string 2.31 µs ± 42.7 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each) ``` Previously, the timing was around `200 ms`. --- dpctl/_sycl_device.pyx | 47 ++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/dpctl/_sycl_device.pyx b/dpctl/_sycl_device.pyx index a2e1b18239..1ab21d7575 100644 --- a/dpctl/_sycl_device.pyx +++ b/dpctl/_sycl_device.pyx @@ -110,6 +110,7 @@ from libc.stdlib cimport free, malloc from ._sycl_platform cimport SyclPlatform import collections +import functools import warnings __all__ = [ @@ -198,6 +199,37 @@ cdef void _init_helper(_SyclDevice device, DPCTLSyclDeviceRef DRef): device._max_work_item_sizes = DPCTLDevice_GetMaxWorkItemSizes3d(DRef) +@functools.cache +def _cached_filter_string(d : SyclDevice): + """ + Internal utility to compute filter_string of input SyclDevice + and cached with `functools.cache`. + + Args: + d (dpctl.SyclDevice): + A device for which to compute the filter string. + Returns: + out(str): + Filter string that can be used to create input device, + if the device is a root (unpartitioned) device. + + Raises: + ValueError: if the input device is a sub-device. + """ + cdef _backend_type BTy + cdef _device_type DTy + cdef int64_t relId = -1 + cdef SyclDevice cd = d + relId = DPCTLDeviceMgr_GetRelativeId(cd._device_ref) + if (relId == -1): + raise ValueError("This SyclDevice is not a root device") + BTy = DPCTLDevice_GetBackend(cd._device_ref) + br_str = _backend_type_to_filter_string_part(BTy) + DTy = DPCTLDevice_GetDeviceType(cd._device_ref) + dt_str = _device_type_to_filter_string_part(DTy) + return ":".join((br_str, dt_str, str(relId))) + + cdef class SyclDevice(_SyclDevice): """ SyclDevice(arg=None) A Python wrapper for the :sycl_device:`sycl::device <>` C++ class. @@ -1360,14 +1392,14 @@ cdef class SyclDevice(_SyclDevice): @property def filter_string(self): - """ For a parent device, returns a fully specified filter selector - string``backend:device_type:relative_id`` selecting the device. + """ For a root device, returns a fully specified filter selector + string ``"backend:device_type:relative_id"`` selecting the device. Returns: str: A Python string representing a filter selector string. Raises: - TypeError: If the device is a sub-devices. + TypeError: If the device is a sub-device. :Example: .. code-block:: python @@ -1387,14 +1419,7 @@ cdef class SyclDevice(_SyclDevice): cdef int64_t relId = -1 pDRef = DPCTLDevice_GetParentDevice(self._device_ref) if (pDRef is NULL): - BTy = DPCTLDevice_GetBackend(self._device_ref) - DTy = DPCTLDevice_GetDeviceType(self._device_ref) - relId = DPCTLDeviceMgr_GetRelativeId(self._device_ref) - if (relId == -1): - raise TypeError("This SyclDevice is not a root device") - br_str = _backend_type_to_filter_string_part(BTy) - dt_str = _device_type_to_filter_string_part(DTy) - return ":".join((br_str, dt_str, str(relId))) + return _cached_filter_string(self) else: # this a sub-device, free it, and raise an exception DPCTLDevice_Delete(pDRef) From 586a2abc26a532ce45fac27505b6786cffe6e08a Mon Sep 17 00:00:00 2001 From: Oleksandr Pavlyk Date: Thu, 16 Mar 2023 12:56:02 -0500 Subject: [PATCH 2/2] Use lru_cache, to support Python 3.8 --- dpctl/_sycl_device.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dpctl/_sycl_device.pyx b/dpctl/_sycl_device.pyx index 1ab21d7575..822d8d2c89 100644 --- a/dpctl/_sycl_device.pyx +++ b/dpctl/_sycl_device.pyx @@ -199,7 +199,7 @@ cdef void _init_helper(_SyclDevice device, DPCTLSyclDeviceRef DRef): device._max_work_item_sizes = DPCTLDevice_GetMaxWorkItemSizes3d(DRef) -@functools.cache +@functools.lru_cache(maxsize=None) def _cached_filter_string(d : SyclDevice): """ Internal utility to compute filter_string of input SyclDevice