33# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE
44
55import threading
6- from typing import Union
6+ from typing import Optional , Union
77
88from cuda .core .experimental ._context import Context , ContextOptions
99from cuda .core .experimental ._memory import AsyncMempool , Buffer , MemoryResource , _SynchronousMemoryResource
10+ from cuda .core .experimental ._event import Event , EventOptions
11+
1012from cuda .core .experimental ._stream import Stream , StreamOptions , default_stream
11- from cuda .core .experimental ._utils import ComputeCapability , CUDAError , driver , handle_return , precondition , runtime
13+ from cuda .core .experimental ._utils .clear_error_support import assert_type
14+ from cuda .core .experimental ._utils .cuda_utils import (
15+ ComputeCapability ,
16+ CUDAError ,
17+ driver ,
18+ handle_return ,
19+ precondition ,
20+ runtime ,
21+ )
1222
1323_tls = threading .local ()
1424_lock = threading .Lock ()
@@ -949,10 +959,11 @@ def __new__(cls, device_id=None):
949959 # important: creating a Device instance does not initialize the GPU!
950960 if device_id is None :
951961 device_id = handle_return (runtime .cudaGetDevice ())
952- assert isinstance (device_id , int ), f" { device_id = } "
962+ assert_type (device_id , int )
953963 else :
954964 total = handle_return (runtime .cudaGetDeviceCount ())
955- if not isinstance (device_id , int ) or not (0 <= device_id < total ):
965+ assert_type (device_id , int )
966+ if not (0 <= device_id < total ):
956967 raise ValueError (f"device_id must be within [0, { total } ), got { device_id } " )
957968
958969 # ensure Device is singleton
@@ -981,7 +992,9 @@ def __new__(cls, device_id=None):
981992
982993 def _check_context_initialized (self , * args , ** kwargs ):
983994 if not self ._has_inited :
984- raise CUDAError ("the device is not yet initialized, perhaps you forgot to call .set_current() first?" )
995+ raise CUDAError (
996+ f"Device { self ._id } is not yet initialized, perhaps you forgot to call .set_current() first?"
997+ )
985998
986999 @property
9871000 def device_id (self ) -> int :
@@ -1053,7 +1066,8 @@ def context(self) -> Context:
10531066
10541067 """
10551068 ctx = handle_return (driver .cuCtxGetCurrent ())
1056- assert int (ctx ) != 0
1069+ if int (ctx ) == 0 :
1070+ raise CUDAError ("No context is bound to the calling CPU thread." )
10571071 return Context ._from_ctx (ctx , self ._id )
10581072
10591073 @property
@@ -1063,8 +1077,7 @@ def memory_resource(self) -> MemoryResource:
10631077
10641078 @memory_resource .setter
10651079 def memory_resource (self , mr ):
1066- if not isinstance (mr , MemoryResource ):
1067- raise TypeError
1080+ assert_type (mr , MemoryResource )
10681081 self ._mr = mr
10691082
10701083 @property
@@ -1118,12 +1131,11 @@ def set_current(self, ctx: Context = None) -> Union[Context, None]:
11181131
11191132 """
11201133 if ctx is not None :
1121- if not isinstance (ctx , Context ):
1122- raise TypeError ("a Context object is required" )
1134+ assert_type (ctx , Context )
11231135 if ctx ._id != self ._id :
11241136 raise RuntimeError (
1125- "the provided context was created on a different "
1126- f"device { ctx ._id } other than the target { self ._id } "
1137+ "the provided context was created on the device with "
1138+ f" id= { ctx ._id } , which is different from the target id= { self ._id } "
11271139 )
11281140 prev_ctx = handle_return (driver .cuCtxPopCurrent ())
11291141 handle_return (driver .cuCtxPushCurrent (ctx ._handle ))
@@ -1165,7 +1177,7 @@ def create_context(self, options: ContextOptions = None) -> Context:
11651177 Newly created context object.
11661178
11671179 """
1168- raise NotImplementedError ("TODO " )
1180+ raise NotImplementedError ("WIP: https://github.com/NVIDIA/cuda-python/issues/189 " )
11691181
11701182 @precondition (_check_context_initialized )
11711183 def create_stream (self , obj = None , options : StreamOptions = None ) -> Stream :
@@ -1198,6 +1210,27 @@ def create_stream(self, obj=None, options: StreamOptions = None) -> Stream:
11981210 """
11991211 return Stream ._init (obj = obj , options = options )
12001212
1213+ @precondition (_check_context_initialized )
1214+ def create_event (self , options : Optional [EventOptions ] = None ) -> Event :
1215+ """Create an Event object without recording it to a Stream.
1216+
1217+ Note
1218+ ----
1219+ Device must be initialized.
1220+
1221+ Parameters
1222+ ----------
1223+ options : :obj:`EventOptions`, optional
1224+ Customizable dataclass for event creation options.
1225+
1226+ Returns
1227+ -------
1228+ :obj:`~_event.Event`
1229+ Newly created event object.
1230+
1231+ """
1232+ return Event ._init (options )
1233+
12011234 @precondition (_check_context_initialized )
12021235 def allocate (self , size , stream = None ) -> Buffer :
12031236 """Allocate device memory from a specified stream.
0 commit comments