@@ -69,7 +69,7 @@ cdef class StridedMemoryView:
6969 obj : Any
7070 Any objects that supports either DLPack (up to v1.0) or CUDA Array
7171 Interface (v3).
72- stream_ptr: Optional[ int]
72+ stream_ptr: int
7373 The pointer address (as Python `int`) to the **consumer** stream.
7474 Stream ordering will be properly established unless ``-1`` is passed.
7575 """
@@ -85,6 +85,11 @@ cdef class StridedMemoryView:
8585 # A strong reference to the result of obj.__dlpack__() so we
8686 # can lazily create shape and strides from it later
8787 cdef object dlpack_capsule
88+
89+ # Memoized properties
90+ cdef tuple _shape
91+ cdef object _strides
92+ cdef object _dtype
8893
8994 def __init__ (self , obj = None , stream_ptr = None ):
9095 if obj is not None :
@@ -98,45 +103,47 @@ cdef class StridedMemoryView:
98103
99104 @property
100105 def shape (self ) -> tuple[int]:
101- if self.exporting_obj is not None:
106+ if self._shape is None and self. exporting_obj is not None:
102107 if self.dl_tensor != NULL:
103- return cuda_utils.carray_int64_t_to_tuple(
108+ self. _shape = cuda_utils.carray_int64_t_to_tuple(
104109 self .dl_tensor.shape,
105110 self .dl_tensor.ndim
106111 )
107112 else:
108- return self.exporting_obj.__cuda_array_interface__["shape"]
109- return ()
113+ self._shape = self .exporting_obj.__cuda_array_interface__[" shape" ]
114+ else:
115+ self._shape = ()
116+ return self._shape
110117
111118 @property
112119 def strides(self ) -> Optional[tuple[int]]:
113120 cdef int itemsize
114- if self.exporting_obj is not None:
121+ if self._strides is None and self. exporting_obj is not None:
115122 if self.dl_tensor != NULL:
116123 if self.dl_tensor.strides:
117- return cuda_utils.carray_int64_t_to_tuple(
124+ self. _strides = cuda_utils.carray_int64_t_to_tuple(
118125 self .dl_tensor.strides,
119126 self .dl_tensor.ndim
120127 )
121128 else:
122129 strides = self .exporting_obj.__cuda_array_interface__.get(" strides" )
123130 if strides is not None:
124131 itemsize = self .dtype.itemsize
125- result = cpython.PyTuple_New(len (strides))
132+ self. _strides = cpython.PyTuple_New(len (strides))
126133 for i in range(len(strides )):
127- cpython.PyTuple_SET_ITEM(result, i, strides[i] // itemsize)
128- return result
129- return None
134+ cpython.PyTuple_SET_ITEM(self ._strides, i, strides[i] // itemsize)
135+ return self ._strides
130136
131137 @property
132138 def dtype (self ) -> Optional[numpy.dtype]:
133- if self.exporting_obj is not None:
134- if self.dl_tensor != NULL:
135- return dtype_dlpack_to_numpy(&self.dl_tensor.dtype )
136- else:
137- # TODO: this only works for built-in numeric types
138- return numpy.dtype(self.exporting_obj.__cuda_array_interface__["typestr"])
139- return None
139+ if self._dtype is None:
140+ if self.exporting_obj is not None:
141+ if self.dl_tensor != NULL:
142+ self._dtype = dtype_dlpack_to_numpy(& self .dl_tensor.dtype)
143+ else:
144+ # TODO: this only works for built-in numeric types
145+ self._dtype = numpy.dtype(self .exporting_obj.__cuda_array_interface__[" typestr" ])
146+ return self._dtype
140147
141148 def __repr__(self ):
142149 return (f" StridedMemoryView(ptr={self.ptr},\n "
0 commit comments