@@ -20,7 +20,59 @@ from cuda.core.experimental._utils import handle_return
20
20
21
21
@cython.dataclasses.dataclass
22
22
cdef class StridedMemoryView:
23
-
23
+ """ A dataclass holding metadata of a strided dense array/tensor.
24
+
25
+ A :obj:`StridedMemoryView` instance can be created in two ways:
26
+
27
+ 1. Using the :obj:`viewable` decorator (recommended)
28
+ 2. Explicit construction, see below
29
+
30
+ This object supports both DLPack (up to v1.0) and CUDA Array Interface
31
+ (CAI) v3. When wrapping an arbitrary object it will try the DLPack protocol
32
+ first, then the CAI protocol. A :obj:`BufferError` is raised if neither is
33
+ supported.
34
+
35
+ Since either way would take a consumer stream, for DLPack it is passed to
36
+ ``obj.__dlpack__()`` as-is (except for :obj:`None`, see below); for CAI, a
37
+ stream order will be established between the consumer stream and the
38
+ producer stream (from ``obj.__cuda_array_interface__()["stream"]``), as if
39
+ ``cudaStreamWaitEvent`` is called by this method.
40
+
41
+ To opt-out of the stream ordering operation in either DLPack or CAI,
42
+ please pass ``stream_ptr=-1``. Note that this deviates (on purpose)
43
+ from the semantics of ``obj.__dlpack__(stream=None, ...)`` since ``cuda.core``
44
+ does not encourage using the (legacy) default/null stream, but is
45
+ consistent with the CAI's semantics. For DLPack, ``stream=-1`` will be
46
+ internally passed to ``obj.__dlpack__()`` instead.
47
+
48
+ Attributes
49
+ ----------
50
+ ptr : int
51
+ Pointer to the tensor buffer (as a Python `int`).
52
+ shape: tuple
53
+ Shape of the tensor.
54
+ strides: tuple
55
+ Strides of the tensor (in **counts**, not bytes).
56
+ dtype: numpy.dtype
57
+ Data type of the tensor.
58
+ device_id: int
59
+ The device ID for where the tensor is located. It is 0 for CPU tensors.
60
+ device_accessible: bool
61
+ Whether the tensor data can be accessed on the GPU.
62
+ readonly: bool
63
+ Whether the tensor data can be modified in place.
64
+ exporting_obj: Any
65
+ A reference to the original tensor object that is being viewed.
66
+
67
+ Parameters
68
+ ----------
69
+ obj : Any
70
+ Any objects that supports either DLPack (up to v1.0) or CUDA Array
71
+ Interface (v3).
72
+ stream_ptr: int
73
+ The pointer address (as Python `int`) to the **consumer** stream.
74
+ Stream ordering will be properly established unless ``-1`` is passed.
75
+ """
24
76
# TODO: switch to use Cython's cdef typing?
25
77
ptr: int = None
26
78
shape: tuple = None
@@ -285,6 +337,33 @@ cdef StridedMemoryView view_as_cai(obj, stream_ptr, view=None):
285
337
286
338
287
339
def viewable (tuple arg_indices ):
340
+ """ Decorator to create proxy objects to :obj:`StridedMemoryView` for the
341
+ specified positional arguments.
342
+
343
+ Inside the decorated function, the specified arguments becomes instances
344
+ of an (undocumented) proxy type, regardless of its original source. A
345
+ :obj:`StridedMemoryView` instance can be obtained by passing the (consumer)
346
+ stream pointer (as a Python `int`) to the proxies's ``view()`` method. For
347
+ example:
348
+
349
+ .. code-block:: python
350
+
351
+ @viewable((1,))
352
+ def my_func(arg0, arg1, arg2, stream: Stream):
353
+ # arg1 can be any object supporting DLPack or CUDA Array Interface
354
+ view = arg1.view(stream.handle)
355
+ assert isinstance(view, StridedMemoryView)
356
+ ...
357
+
358
+ This allows array/tensor attributes to be accessed inside the function
359
+ implementation, while keeping the function body array-library-agnostic (if
360
+ desired).
361
+
362
+ Parameters
363
+ ----------
364
+ arg_indices : tuple
365
+ The indices of the target positional arguments.
366
+ """
288
367
def wrapped_func_with_indices (func ):
289
368
@ functools.wraps (func)
290
369
def wrapped_func (*args , **kwargs ):
0 commit comments