make SequentialOrderManager thread-local and cached queues, devices g… · IntelPython/dpctl@549cfa2 · GitHub
Skip to content

Commit 549cfa2

Browse files
committed
make SequentialOrderManager thread-local and cached queues, devices global
1 parent fde8d0a commit 549cfa2

4 files changed

Lines changed: 75 additions & 100 deletions

File tree

dpctl/_sycl_device_factory.pyx

Lines changed: 36 additions & 46 deletions

dpctl/_sycl_queue_manager.pyx

Lines changed: 18 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
# cython: freethreading_compatible = True
2121

2222
import logging
23-
from contextvars import ContextVar
23+
import threading
2424
from ._sycl_context cimport SyclContext
2525
from ._sycl_device cimport SyclDevice
2626

@@ -34,13 +34,14 @@ _logger = logging.getLogger(__name__)
3434

3535
cdef class _DeviceDefaultQueueCache:
3636
cdef dict __device_queue_map__
37+
cdef object _cache_lock
3738

3839
def __cinit__(self):
3940
self.__device_queue_map__ = {}
41+
self._cache_lock = threading.Lock()
4042

4143
def get_or_create(self, key):
42-
"""Return instance of SyclQueue and indicator if cache
43-
has been modified"""
44+
"""Return cached SyclQueue for given key, creating it if needed."""
4445
if (
4546
isinstance(key, tuple)
4647
and len(key) == 2
@@ -57,14 +58,15 @@ cdef class _DeviceDefaultQueueCache:
5758
ctx_dev = q.sycl_context, q.sycl_device
5859
else:
5960
raise TypeError
60-
if ctx_dev in self.__device_queue_map__:
61-
return self.__device_queue_map__[ctx_dev], False
62-
if q is None:
63-
q = SyclQueue(*ctx_dev)
64-
self.__device_queue_map__[ctx_dev] = q
65-
return q, True
66-
67-
cdef _update_map(self, dev_queue_map):
61+
with self._cache_lock:
62+
if ctx_dev in self.__device_queue_map__:
63+
return self.__device_queue_map__[ctx_dev]
64+
if q is None:
65+
q = SyclQueue(*ctx_dev)
66+
self.__device_queue_map__[ctx_dev] = q
67+
return q
68+
69+
def _update_map(self, dev_queue_map):
6870
self.__device_queue_map__.update(dev_queue_map)
6971

7072
def __copy__(self):
@@ -75,29 +77,13 @@ cdef class _DeviceDefaultQueueCache:
7577
return _copy
7678

7779

78-
# no default, as would share a single mutable instance across threads and
79-
# concurrent access to the cache would not be thread-safe. Using ContextVar
80-
# without a default ensures each context gets its own instance.
81-
_global_device_queue_cache = ContextVar(
82-
"global_device_queue_cache",
83-
)
84-
85-
86-
cdef _DeviceDefaultQueueCache _get_device_queue_cache():
87-
"""
88-
Factory function to get or create a default device queue cache for the
89-
current context
90-
"""
91-
try:
92-
return _global_device_queue_cache.get()
93-
except LookupError:
94-
cache = _DeviceDefaultQueueCache()
95-
_global_device_queue_cache.set(cache)
96-
return cache
80+
# all threads share the same cached default
81+
_global_device_queue_cache = _DeviceDefaultQueueCache()
9782

9883

9984
cpdef object get_device_cached_queue(object key):
100-
"""Returns a cached queue associated with given device.
85+
"""
86+
Returns a cached queue associated with given device.
10187
10288
Args:
10389
key : Either a 2-tuple consisting of a :class:`dpctl.SyclContext` and
@@ -112,8 +98,4 @@ cpdef object get_device_cached_queue(object key):
11298
TypeError: If the input key is not one of the accepted types.
11399
114100
"""
115-
_cache = _get_device_queue_cache()
116-
q_, changed_ = _cache.get_or_create(key)
117-
if changed_:
118-
_global_device_queue_cache.set(_cache)
119-
return q_
101+
return _global_device_queue_cache.get_or_create(key)

dpctl/tests/test_sycl_queue_manager.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,20 @@
2424
def test__DeviceDefaultQueueCache():
2525
import copy
2626

27-
from dpctl._sycl_queue_manager import _global_device_queue_cache as cache
28-
from dpctl._sycl_queue_manager import get_device_cached_queue
27+
from dpctl._sycl_queue_manager import (
28+
_global_device_queue_cache,
29+
get_device_cached_queue,
30+
)
2931

3032
try:
3133
d = dpctl.SyclDevice()
3234
except dpctl.SyclDeviceCreationError:
3335
pytest.skip("Could not create default device")
3436

3537
q1 = get_device_cached_queue(d)
36-
cache_copy = copy.copy(cache.get())
37-
q2, changed = cache_copy.get_or_create(d)
38+
cache_copy = copy.copy(_global_device_queue_cache)
39+
q2 = cache_copy.get_or_create(d)
3840

39-
assert not changed
4041
assert q1 == q2
4142
q3 = get_device_cached_queue(d.filter_string)
4243
assert q3 == q1

dpctl/utils/_order_manager.py

Lines changed: 15 additions & 13 deletions

0 commit comments

Comments
 (0)