Skip to content

Commit 7a86fbf

Browse files
Merge pull request #826 from IntelPython/device-creation-error
Raises dedicate exception type of failure to create SyclDevice
2 parents ecae1c6 + 662e519 commit 7a86fbf

File tree

9 files changed

+127
-61
lines changed

9 files changed

+127
-61
lines changed

dpctl/__init__.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,12 @@
3232
"""
3333
__author__ = "Intel Corp."
3434

35-
from dpctl._sycl_context import SyclContext
36-
from dpctl._sycl_device import SyclDevice
35+
from dpctl._sycl_context import SyclContext, SyclContextCreationError
36+
from dpctl._sycl_device import (
37+
SyclDevice,
38+
SyclDeviceCreationError,
39+
SyclSubDeviceCreationError,
40+
)
3741
from dpctl._sycl_device_factory import (
3842
get_devices,
3943
get_num_devices,
@@ -73,9 +77,12 @@
7377

7478
__all__ = [
7579
"SyclContext",
80+
"SyclContextCreationError",
7681
]
7782
__all__ += [
7883
"SyclDevice",
84+
"SyclDeviceCreationError",
85+
"SyclSubDeviceCreationError",
7986
]
8087
__all__ += [
8188
"get_devices",

dpctl/_device_selection.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import collections.abc
22
from itertools import chain
33

4-
from . import SyclDevice, get_devices
4+
from ._sycl_device import SyclDevice, SyclDeviceCreationError
5+
from ._sycl_device_factory import get_devices
56

67

78
def select_device_with_aspects(required_aspects, excluded_aspects=[]):
@@ -66,7 +67,7 @@ def select_device_with_aspects(required_aspects, excluded_aspects=[]):
6667
selected_dev = dev
6768

6869
if selected_dev is None:
69-
raise ValueError(
70+
raise SyclDeviceCreationError(
7071
f"Requested device is unavailable: "
7172
f"required_aspects={required_aspects}, "
7273
f"excluded_aspects={excluded_aspects}"

dpctl/_sycl_context.pyx

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,25 @@ from ._backend cimport ( # noqa: E211
4949
)
5050
from ._sycl_device cimport SyclDevice
5151
from ._sycl_queue cimport default_async_error_handler
52+
from ._sycl_device import SyclDeviceCreationError
5253

5354
__all__ = [
5455
"SyclContext",
56+
"SyclContextCreationError",
5557
]
5658

5759
_logger = logging.getLogger(__name__)
5860

61+
62+
cdef class SyclContextCreationError(Exception):
63+
"""
64+
A SyclContextCreationError exception is raised when
65+
SyclContext could not created.
66+
67+
"""
68+
pass
69+
70+
5971
cdef void _context_capsule_deleter(object o):
6072
cdef DPCTLSyclContextRef CRef = NULL
6173
if pycapsule.PyCapsule_IsValid(o, "SyclContextRef"):
@@ -162,7 +174,8 @@ cdef class SyclContext(_SyclContext):
162174
Raises:
163175
MemoryError: If the constructor could not allocate necessary
164176
temporary memory.
165-
ValueError: If the :class:`dpctl.SyclContext` object creation failed.
177+
SyclContextCreationError: If the :class:`dpctl.SyclContext` object
178+
creation failed.
166179
TypeError: If the list of :class:`dpctl.SyclDevice` objects was empty,
167180
or the input capsule contained a null pointer or could not
168181
be renamed.
@@ -283,11 +296,17 @@ cdef class SyclContext(_SyclContext):
283296
):
284297
ret = self._init_context_from_devices(arg, 0)
285298
else:
286-
dev = SyclDevice(arg)
299+
try:
300+
dev = SyclDevice(arg)
301+
except SyclDeviceCreationError as e:
302+
raise SyclContextCreationError(
303+
"SyclContext failed to be created because "
304+
f"SyclDevice could not be created from the argument {arg}"
305+
) from e
287306
ret = self._init_context_from_one_device(<SyclDevice> dev, 0)
288307
if (ret < 0):
289308
if (ret == -1):
290-
raise ValueError("Context failed to be created.")
309+
raise SyclContextCreationError("Context failed to be created.")
291310
elif (ret == -2):
292311
raise TypeError(
293312
"List of devices to create context from must be non-empty."

dpctl/_sycl_device.pyx

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,22 @@ import collections
9595
import warnings
9696

9797
__all__ = [
98-
"SyclDevice",
98+
"SyclDevice", "SyclDeviceCreationError", "SyclSubDeviceCreationError",
9999
]
100100

101101

102-
cdef class SubDeviceCreationError(Exception):
102+
cdef class SyclDeviceCreationError(Exception):
103103
"""
104-
A SubDeviceCreationError exception is raised when
104+
A SyclDeviceCreationError exception is raised when
105+
SyclDevice instance could not created.
106+
107+
"""
108+
pass
109+
110+
111+
cdef class SyclSubDeviceCreationError(Exception):
112+
"""
113+
A SyclSubDeviceCreationError exception is raised when
105114
sub-devices were not created.
106115
107116
"""
@@ -165,6 +174,7 @@ cdef str _device_type_to_filter_string_part(_device_type DTy):
165174
else:
166175
return "unknown"
167176

177+
168178
cdef void _init_helper(_SyclDevice device, DPCTLSyclDeviceRef DRef):
169179
"Populate attributes of device from opaque device reference DRef"
170180
device._device_ref = DRef
@@ -213,6 +223,20 @@ cdef class SyclDevice(_SyclDevice):
213223
gpu = dpctl.select_gpu_device():
214224
gpu.print_device_info()
215225
226+
Args:
227+
arg (optional): The argument can be a selector string or None.
228+
Defaults to ``None``.
229+
230+
Raises:
231+
MemoryError: If the constructor could not allocate necessary
232+
temporary memory.
233+
SyclDeviceCreationError: If the :class:`dpctl.SyclDevice` object
234+
creation failed.
235+
TypeError: If the list of :class:`dpctl.SyclDevice` objects was empty,
236+
or the input capsule contained a null pointer or could not
237+
be renamed.
238+
239+
216240
"""
217241
@staticmethod
218242
cdef SyclDevice _create(DPCTLSyclDeviceRef dref):
@@ -262,20 +286,20 @@ cdef class SyclDevice(_SyclDevice):
262286
DSRef = DPCTLFilterSelector_Create(filter_c_str)
263287
ret = self._init_from_selector(DSRef)
264288
if ret == -1:
265-
raise ValueError(
289+
raise SyclDeviceCreationError(
266290
"Could not create a SyclDevice with the selector string"
267291
)
268292
elif isinstance(arg, _SyclDevice):
269293
ret = self._init_from__SyclDevice(arg)
270294
if ret == -1:
271-
raise ValueError(
295+
raise SyclDeviceCreationError(
272296
"Could not create a SyclDevice from _SyclDevice instance"
273297
)
274298
elif arg is None:
275299
DSRef = DPCTLDefaultSelector_Create()
276300
ret = self._init_from_selector(DSRef)
277301
if ret == -1:
278-
raise ValueError(
302+
raise SyclDeviceCreationError(
279303
"Could not create a SyclDevice from default selector"
280304
)
281305
else:
@@ -746,7 +770,7 @@ cdef class SyclDevice(_SyclDevice):
746770
if count > 0:
747771
DVRef = DPCTLDevice_CreateSubDevicesEqually(self._device_ref, count)
748772
if DVRef is NULL:
749-
raise SubDeviceCreationError(
773+
raise SyclSubDeviceCreationError(
750774
"Sub-devices were not created." if (count > 0) else
751775
"Sub-devices were not created, "
752776
"requested compute units count was zero."
@@ -785,7 +809,7 @@ cdef class SyclDevice(_SyclDevice):
785809
)
786810
free(counts_buff)
787811
if DVRef is NULL:
788-
raise SubDeviceCreationError(
812+
raise SyclSubDeviceCreationError(
789813
"Sub-devices were not created." if (min_count > 0) else
790814
"Sub-devices were not created, "
791815
"sub-device execution units counts must be positive."
@@ -801,7 +825,7 @@ cdef class SyclDevice(_SyclDevice):
801825
cdef DPCTLDeviceVectorRef DVRef = NULL
802826
DVRef = DPCTLDevice_CreateSubDevicesByAffinity(self._device_ref, domain)
803827
if DVRef is NULL:
804-
raise SubDeviceCreationError("Sub-devices were not created.")
828+
raise SyclSubDeviceCreationError("Sub-devices were not created.")
805829
return _get_devices(DVRef)
806830

807831
def create_sub_devices(self, **kwargs):

dpctl/_sycl_device_factory.pyx

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ from ._backend cimport ( # noqa: E211
4646
_device_type,
4747
)
4848

49+
from ._sycl_device import SyclDeviceCreationError
4950
from .enum_types import backend_type
5051
from .enum_types import device_type as device_type_t
5152

@@ -307,15 +308,15 @@ cpdef SyclDevice select_accelerator_device():
307308
dpctl.SyclDevice: A Python object wrapping the SYCL ``device``
308309
returned by the SYCL ``accelerator_selector``.
309310
Raises:
310-
ValueError: If the SYCL ``accelerator_selector`` is unable to select a
311-
``device``.
311+
dpctl.SyclDeviceCreatioError: If the SYCL ``accelerator_selector`` is
312+
unable to select a ``device``.
312313
"""
313314
cdef DPCTLSyclDeviceSelectorRef DSRef = DPCTLAcceleratorSelector_Create()
314315
cdef DPCTLSyclDeviceRef DRef = DPCTLDevice_CreateFromSelector(DSRef)
315316
# Free up the device selector
316317
DPCTLDeviceSelector_Delete(DSRef)
317318
if DRef is NULL:
318-
raise ValueError("Device unavailable.")
319+
raise SyclDeviceCreationError("Accelerator device is unavailable.")
319320
Device = SyclDevice._create(DRef)
320321
return Device
321322

@@ -327,15 +328,15 @@ cpdef SyclDevice select_cpu_device():
327328
dpctl.SyclDevice: A Python object wrapping the SYCL ``device``
328329
returned by the SYCL ``cpu_selector``.
329330
Raises:
330-
ValueError: If the SYCL ``cpu_selector`` is unable to select a
331-
``device``.
331+
dpctl.SyclDeviceCreationError: If the SYCL ``cpu_selector`` is
332+
unable to select a ``device``.
332333
"""
333334
cdef DPCTLSyclDeviceSelectorRef DSRef = DPCTLCPUSelector_Create()
334335
cdef DPCTLSyclDeviceRef DRef = DPCTLDevice_CreateFromSelector(DSRef)
335336
# Free up the device selector
336337
DPCTLDeviceSelector_Delete(DSRef)
337338
if DRef is NULL:
338-
raise ValueError("Device unavailable.")
339+
raise SyclDeviceCreationError("CPU device is unavailable.")
339340
Device = SyclDevice._create(DRef)
340341
return Device
341342

@@ -347,15 +348,15 @@ cpdef SyclDevice select_default_device():
347348
dpctl.SyclDevice: A Python object wrapping the SYCL ``device``
348349
returned by the SYCL ``default_selector``.
349350
Raises:
350-
ValueError: If the SYCL ``default_selector`` is unable to select a
351-
``device``.
351+
dpctl.SyclDeviceCreationError: If the SYCL ``default_selector`` is
352+
unable to select a ``device``.
352353
"""
353354
cdef DPCTLSyclDeviceSelectorRef DSRef = DPCTLDefaultSelector_Create()
354355
cdef DPCTLSyclDeviceRef DRef = DPCTLDevice_CreateFromSelector(DSRef)
355356
# Free up the device selector
356357
DPCTLDeviceSelector_Delete(DSRef)
357358
if DRef is NULL:
358-
raise ValueError("Device unavailable.")
359+
raise SyclDeviceCreationError("Default device is unavailable.")
359360
Device = SyclDevice._create(DRef)
360361
return Device
361362

@@ -367,15 +368,15 @@ cpdef SyclDevice select_gpu_device():
367368
dpctl.SyclDevice: A Python object wrapping the SYCL ``device``
368369
returned by the SYCL ``gpu_selector``.
369370
Raises:
370-
ValueError: If the SYCL ``gpu_selector`` is unable to select a
371-
``device``.
371+
dpctl.SyclDeviceCreationError: If the SYCL ``gpu_selector`` is
372+
unable to select a ``device``.
372373
"""
373374
cdef DPCTLSyclDeviceSelectorRef DSRef = DPCTLGPUSelector_Create()
374375
cdef DPCTLSyclDeviceRef DRef = DPCTLDevice_CreateFromSelector(DSRef)
375376
# Free up the device selector
376377
DPCTLDeviceSelector_Delete(DSRef)
377378
if DRef is NULL:
378-
raise ValueError("Device unavailable.")
379+
raise SyclDeviceCreationError("Device unavailable.")
379380
Device = SyclDevice._create(DRef)
380381
return Device
381382

@@ -387,14 +388,14 @@ cpdef SyclDevice select_host_device():
387388
dpctl.SyclDevice: A Python object wrapping the SYCL ``device``
388389
returned by the SYCL ``host_selector``.
389390
Raises:
390-
ValueError: If the SYCL ``host_selector`` is unable to select a
391-
``device``.
391+
dpctl.SyclDeviceCreationError: If the SYCL ``host_selector`` is
392+
unable to select a ``device``.
392393
"""
393394
cdef DPCTLSyclDeviceSelectorRef DSRef = DPCTLHostSelector_Create()
394395
cdef DPCTLSyclDeviceRef DRef = DPCTLDevice_CreateFromSelector(DSRef)
395396
# Free up the device selector
396397
DPCTLDeviceSelector_Delete(DSRef)
397398
if DRef is NULL:
398-
raise ValueError("Device unavailable.")
399+
raise SyclDeviceCreationError("Host device is unavailable.")
399400
Device = SyclDevice._create(DRef)
400401
return Device

dpctl/tests/test_sycl_context.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def test_ctxt_creation_from_filter(valid_filter):
5050
"""
5151
try:
5252
dpctl.SyclContext(valid_filter)
53-
except ValueError:
53+
except dpctl.SyclContextCreationError:
5454
pytest.skip("Failed to create context with supported filter")
5555

5656

@@ -70,11 +70,11 @@ def test_context_not_equals():
7070
"""
7171
try:
7272
ctx_gpu = dpctl.SyclContext("gpu")
73-
except ValueError:
73+
except dpctl.SyclContextCreationError:
7474
pytest.skip()
7575
try:
7676
ctx_cpu = dpctl.SyclContext("cpu")
77-
except ValueError:
77+
except dpctl.SyclContextCreationError:
7878
pytest.skip()
7979
assert ctx_cpu != ctx_gpu
8080
assert hash(ctx_cpu) != hash(ctx_gpu)
@@ -93,7 +93,7 @@ def test_context_equals():
9393
try:
9494
ctx1 = dpctl.SyclContext("gpu")
9595
ctx0 = dpctl.SyclContext("gpu")
96-
except ValueError:
96+
except dpctl.SyclContextCreationError:
9797
pytest.skip()
9898
assert ctx0 == ctx1
9999
assert hash(ctx0) == hash(ctx1)
@@ -118,7 +118,7 @@ def test_repr():
118118
def test_context_can_be_used_in_queue(valid_filter):
119119
try:
120120
ctx = dpctl.SyclContext(valid_filter)
121-
except ValueError:
121+
except dpctl.SyclContextCreationError:
122122
pytest.skip()
123123
devs = ctx.get_devices()
124124
assert len(devs) == ctx.device_count
@@ -129,7 +129,7 @@ def test_context_can_be_used_in_queue(valid_filter):
129129
def test_context_can_be_used_in_queue2(valid_filter):
130130
try:
131131
d = dpctl.SyclDevice(valid_filter)
132-
except ValueError:
132+
except dpctl.SyclDeviceCreationError:
133133
pytest.skip()
134134
if d.default_selector_score < 0:
135135
# skip test for devices rejected by default selector
@@ -141,7 +141,7 @@ def test_context_can_be_used_in_queue2(valid_filter):
141141
def test_context_multi_device():
142142
try:
143143
d = dpctl.SyclDevice("cpu")
144-
except ValueError:
144+
except dpctl.SyclDeviceCreationError:
145145
pytest.skip()
146146
if d.default_selector_score < 0:
147147
pytest.skip()
@@ -244,5 +244,5 @@ def test_invalid_capsule():
244244
def test_multi_device_different_platforms():
245245
devs = dpctl.get_devices() # all devices
246246
if len(devs) > 1:
247-
with pytest.raises(ValueError):
247+
with pytest.raises(dpctl.SyclContextCreationError):
248248
dpctl.SyclContext(devs)

0 commit comments

Comments
 (0)