2222
2323from __future__ import print_function
2424import logging
25- from ._backend cimport (
25+ from ._backend cimport(
2626 DPCTLSyclContextRef,
2727 DPCTLSyclDeviceRef,
2828 DPCTLContext_Create,
@@ -69,20 +69,93 @@ cdef class _SyclContext:
6969
7070
7171cdef class SyclContext(_SyclContext):
72- """ Python class representing cl::sycl::context.
72+ """
73+ Python class representing ``cl::sycl::context``. There are multiple
74+ ways to create a :class:`dpctl.SyclContext` object:
75+
76+ - Invoking the constructor with no arguments creates a context using
77+ the default selector.
78+
79+ :Example:
80+ .. code-block:: python
81+
82+ import dpctl
83+
84+ # Create a default SyclContext
85+ ctx = dpctl.SyclContext()
86+ print(ctx.get_devices())
87+
88+ - Invoking the constuctor with a specific filter string that creates a
89+ context for the device corresponding to the filter string.
90+
91+ :Example:
92+ .. code-block:: python
93+
94+ import dpctl
95+
96+ # Create a default SyclContext
97+ ctx = dpctl.SyclContext("gpu")
98+ d = ctx.get_devices()[0]
99+ assert(d.is_gpu)
100+
101+ - Invoking the constuctor with a :class:`dpctl.SyclDevice` object
102+ creates a context for that device.
103+
104+ :Example:
105+ .. code-block:: python
106+
107+ import dpctl
108+
109+ # Create a level zero gpu device
110+ d = dpctl.SyclDevice("level_zero:gpu")
111+ ctx = dpctl.SyclContext(d)
112+ d = ctx.get_devices()[0]
113+ assert(d.is_gpu)
114+
115+ - Invoking the constuctor with a list of :class:`dpctl.SyclDevice`
116+ objects creates a common context for all the devices. This
117+ constructor call is especially useful when creation a context for
118+ multiple sub-devices.
119+
120+ :Example:
121+ .. code-block:: python
122+
123+ import dpctl
124+
125+ # Create a CPU device using the opencl driver
126+ cpu_d = dpctl.SyclDevice("opencl:cpu")
127+ # Partition the CPU device into sub-devices, each with two cores.
128+ sub_devices = create_sub_devices(partition=2)
129+ # Create a context common to all the sub-devices.
130+ ctx = dpctl.SyclContext(sub_devices)
131+ assert(len(ctx.get_devices) == len(sub_devices))
132+
133+ - Invoking the constuctor with a named ``PyCapsule`` with the name
134+ **SyclContextRef** that carries a pointer to a ``sycl::context``
135+ object.
136+
137+ Args:
138+ arg (optional): Defaults to None.
139+ The argument can be a :class:`dpctl.SyclDevice` instance,
140+ a :obj:`list` of :class:`dpctl.SyclDevice` objects, or a named
141+ ``PyCapsule`` called **SyclContextRef**.
142+
143+ Raises:
144+ MemoryError: If the constructor could not allocate necessary
145+ temporary memory.
146+ ValueError: If the :class:`dpctl.SyclContext` object creation failed.
147+ TypeError: If the list of :class:`dpctl.SyclDevice` objects was empty,
148+ or the input capsule contained a null pointer or could not
149+ be renamed.
73150
74- SyclContext() - create a context for a default device
75- SyclContext(filter_selector_string) - create a context for specified device
76- SyclContext(SyclDevice_instance) - create a context for the given device
77- SyclContext((dev1, dev2, ...)) - create a context for given set of device instances
78151 """
79-
152+
80153 @staticmethod
81154 cdef void _init_helper(_SyclContext context, DPCTLSyclContextRef CRef):
82155 context._ctxt_ref = CRef
83-
156+
84157 @staticmethod
85- cdef SyclContext _create (DPCTLSyclContextRef ctxt):
158+ cdef SyclContext _create(DPCTLSyclContextRef ctxt):
86159 """
87160 Calls DPCTLContext_Delete(ctxt).
88161
@@ -155,15 +228,18 @@ cdef class SyclContext(_SyclContext):
155228
156229 cdef int _init_context_from_capsule(self , object cap):
157230 """
158- For named PyCapsule with name SyclContextRef, which carries pointer to
159- sycl::context object, interpreted as DPCTLSyclContextRef, creates corresponding
160- SyclContext.
231+ For named ``PyCapsule`` with name **SyclContextRef**, which carries
232+ pointer to ``sycl::context`` object, interpreted as
233+ ``DPCTLSyclContextRef``, creates corresponding
234+ :class:`dpctl.SyclContext`.
161235 """
162236 cdef DPCTLSyclContextRef CRef = NULL
163237 cdef DPCTLSyclContextRef CRef_copy = NULL
164238 cdef int ret = 0
165239 if pycapsule.PyCapsule_IsValid(cap, " SyclContextRef" ):
166- CRef = < DPCTLSyclContextRef> pycapsule.PyCapsule_GetPointer(cap, " SyclContextRef" )
240+ CRef = < DPCTLSyclContextRef> pycapsule.PyCapsule_GetPointer(
241+ cap, " SyclContextRef"
242+ )
167243 if (CRef is NULL ):
168244 return - 6
169245 ret = pycapsule.PyCapsule_SetName(cap, " used_SyclContextRef" )
@@ -188,7 +264,9 @@ cdef class SyclContext(_SyclContext):
188264 ret = self ._init_context_from_one_device(< SyclDevice> arg, 0 )
189265 elif pycapsule.PyCapsule_IsValid(arg, " SyclContextRef" ):
190266 status = self ._init_context_from_capsule(arg)
191- elif isinstance (arg, (list , tuple )) and all ([isinstance (argi, SyclDevice) for argi in arg]):
267+ elif isinstance (
268+ arg, (list , tuple )) and all ([isinstance (argi, SyclDevice) for argi in arg]
269+ ):
192270 ret = self ._init_context_from_devices(arg, 0 )
193271 else :
194272 dev = SyclDevice(arg)
@@ -197,41 +275,74 @@ cdef class SyclContext(_SyclContext):
197275 if (ret == - 1 ):
198276 raise ValueError (" Context failed to be created." )
199277 elif (ret == - 2 ):
200- raise TypeError (" List of devices to create context from must be non-empty." )
278+ raise TypeError (
279+ " List of devices to create context from must be non-empty."
280+ )
201281 elif (ret == - 3 ):
202- raise MemoryError (" Could not allocate necessary temporary memory." )
282+ raise MemoryError (
283+ " Could not allocate necessary temporary memory."
284+ )
203285 elif (ret == - 4 ) or (ret == - 7 ):
204- raise ValueError (" Internal Error: Could not create a copy of a sycl device." )
286+ raise ValueError (
287+ " Internal Error: Could not create a copy of a sycl device."
288+ )
205289 elif (ret == - 5 ):
206- raise ValueError (" Internal Error: Creation of DeviceVector failed." )
290+ raise ValueError (
291+ " Internal Error: Creation of DeviceVector failed."
292+ )
207293 elif (ret == - 6 ):
208- raise TypeError (" Input capsule {} contains a null pointer or could not be renamed" .format(arg))
209- raise ValueError (" Unrecognized error code ({}) encountered." .format(ret))
294+ raise TypeError (
295+ " Input capsule {} contains a null pointer or could not be"
296+ " renamed" .format(arg)
297+ )
298+ raise ValueError (
299+ " Unrecognized error code ({}) encountered." .format(ret)
300+ )
301+
302+ cpdef bool equals(self , SyclContext ctxt):
303+ """
304+ Returns true if the :class:`dpctl.SyclContext` argument has the
305+ same underlying ``DPCTLSyclContextRef`` object as this
306+ :class:`dpctl.SyclContext` instance.
210307
211- cpdef bool equals (self , SyclContext ctxt):
212- """ Returns true if the SyclContext argument has the same _context_ref
213- as this SyclContext.
308+ Returns:
309+ :obj:`bool`: ``True`` if the two :class:`dpctl.SyclContext` objects
310+ point to the same ``DPCTLSyclContextRef`` object, otherwise
311+ ``False``.
214312 """
215313 return DPCTLContext_AreEq(self ._ctxt_ref, ctxt.get_context_ref())
216314
217- cdef DPCTLSyclContextRef get_context_ref (self ):
315+ cdef DPCTLSyclContextRef get_context_ref(self ):
218316 return self ._ctxt_ref
219317
220318 def addressof_ref (self ):
221319 """
222- Returns the address of the DPCTLSyclContextRef pointer as a size_t.
320+ Returns the address of the ``DPCTLSyclContextRef`` pointer as a
321+ ``size_t``.
223322
224323 Returns:
225- The address of the DPCTLSyclContextRef object used to create this
226- SyclContext cast to a size_t.
324+ :obj:`int`: The address of the ``DPCTLSyclContextRef`` object
325+ used to create this :class:`dpctl.SyclContext` cast to a
326+ ``size_t``.
227327 """
228328 return int (< size_t> self ._ctx_ref)
229329
230- def get_devices (self ):
330+ def get_devices (self ):
231331 """
232- Returns the list of SyclDevice objects associated with SyclContext instance.
332+ Returns the list of :class:`dpctl.SyclDevice` objects associated with
333+ :class:`dpctl.SyclContext` instance.
334+
335+ Returns:
336+ :obj:`list`: A :obj:`list` of :class:`dpctl.SyclDevice` objects
337+ that belong to this context.
338+
339+ Raises:
340+ ValueError: If the ``DPCTLContext_GetDevices`` call returned
341+ ``NULL`` instead of a ``DPCTLDeviceVectorRef`` object.
233342 """
234- cdef DPCTLDeviceVectorRef DVRef = DPCTLContext_GetDevices(self .get_context_ref())
343+ cdef DPCTLDeviceVectorRef DVRef = DPCTLContext_GetDevices(
344+ self .get_context_ref()
345+ )
235346 cdef size_t num_devs
236347 cdef size_t i
237348 cdef DPCTLSyclDeviceRef DRef
@@ -244,34 +355,86 @@ cdef class SyclContext(_SyclContext):
244355 devices.append(SyclDevice._create(DRef))
245356 DPCTLDeviceVector_Delete(DVRef)
246357 return devices
247-
358+
248359 @property
249- def device_count (self ):
360+ def device_count (self ):
250361 """
251- The number of sycl devices associated with SyclContext instance.
362+ The number of sycl devices associated with the
363+ :class:`dpctl.SyclContext` instance.
364+
365+ Returns:
366+ :obj:`int`: Number of devices associated with the context.
367+
368+ Raises:
369+ ValueError: If ``DPCTLContext_DeviceCount`` led to a
370+ failure.
252371 """
253372 cdef size_t num_devs = DPCTLContext_DeviceCount(self .get_context_ref())
254373 if num_devs:
255374 return num_devs
256375 else :
257- raise ValueError (" An error was encountered quering the number of devices "
258- " associated with this context" )
376+ raise ValueError (
377+ " An error was encountered quering the number of devices "
378+ " associated with this context"
379+ )
259380
260381 @property
261382 def __name__ (self ):
262383 return " SyclContext"
263384
264385 def __repr__ (self ):
386+ """
387+ Returns the name of the class and number of devices in the context.
388+
389+ :Example:
390+ .. code-block:: python
391+
392+ import dpctl
393+
394+ # Create a default SyclContext
395+ ctx = dpctl.SyclContext()
396+ print(ctx) # E.g : <dpctl.SyclContext at 0x7f154d8ab070>
397+
398+ cpu_d = dpctl.SyclDevice("opencl:cpu")
399+ sub_devices = create_sub_devices(partition=2)
400+ ctx2 = dpctl.SyclContext(sub_devices)
401+ print(ctx2) # E.g : <dpctl.SyclContext for 4 devices at 0x7f154d8ab070>
402+
403+ Returns:
404+ :obj:`str`: A string representation of the
405+ :class:`dpctl.SyclContext` object.
406+
407+ """
265408 cdef size_t n = self .device_count
266409 if n == 1 :
267410 return (" <dpctl." + self .__name__ + " at {}>" .format(hex (id (self ))))
268411 else :
269- return (" <dpctl." + self .__name__ + " for {} devices at {}>" .format(n, hex (id (self ))))
412+ return (" <dpctl." + self .__name__ + " for {} devices at {}>"
413+ .format(n, hex (id (self ))))
270414
271415 def _get_capsule (self ):
416+ """
417+ Returns a copy of the underlying ``sycl::context`` pointer as a void
418+ pointer inside a named ``PyCapsule`` that has the name
419+ **SyclContextRef**. The ownership of the pointer inside the capsule is
420+ passed to the caller, and pointer is deleted when the capsule goes out
421+ of scope.
422+
423+ Returns:
424+ :class:`pycapsule`: A capsule object storing a copy of the
425+ ``sycl::context`` pointer belonging to thus
426+ :class:`dpctl.SyclContext` instance.
427+
428+ Raises:
429+ ValueError: If the ``DPCTLContext_Copy`` fails to copy the
430+ ``sycl::context`` pointer.
431+ """
272432 cdef DPCTLSyclContextRef CRef = NULL
273433 CRef = DPCTLContext_Copy(self ._ctxt_ref)
274434 if (CRef is NULL ):
275435 raise ValueError (" SyclContext copy failed." )
276- return pycapsule.PyCapsule_New(< void * > CRef, " SyclContextRef" , & _context_capsule_deleter)
277-
436+ return pycapsule.PyCapsule_New(
437+ < void * > CRef,
438+ " SyclContextRef" ,
439+ & _context_capsule_deleter
440+ )
0 commit comments