Coverage for cuda/core/_memoryview.pyx: 77.20%

715 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-16 01:23 +0000

1# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 

2# 

3# SPDX-License-Identifier: Apache-2.0 

4  

5from __future__ import annotations 

6  

7cimport cython 

8from ._dlpack cimport * 

9from ._dlpack import classify_dl_device 

10from libc.stdint cimport intptr_t 

11from cuda.core._layout cimport _StridedLayout, get_strides_ptr 

12from cuda.core._stream import Stream 

13  

14import ctypes 

15import functools 

16import sys 

17import warnings 

18from collections.abc import Callable # no-cython-lint # used in string annotations below 

19from typing import TYPE_CHECKING, Any # no-cython-lint # used in string annotations below 

20  

21if TYPE_CHECKING: 

22 from cuda.core._tensor_map import TensorMapDescriptorOptions 

23  

24import numpy 

25  

26from cuda.bindings cimport cydriver 

27from cuda.core._rt cimport ( 

28 EventHandle, 

29 create_event_handle_for_stream, 

30 as_cu, 

31 get_last_error, 

32) 

33  

34from cuda.core._utils.cuda_utils import handle_return, driver 

35from cuda.core._utils.cuda_utils cimport HANDLE_RETURN 

36  

37  

38from cuda.core._memory import Buffer 

39from cuda.core._memory._buffer cimport Buffer as cyBuffer, Buffer_check_open 

40  

41  

42# --------------------------------------------------------------------------- 

43# Lazy tensor bridge (avoids loading _tensor_bridge.so until torch is used) 

44# --------------------------------------------------------------------------- 

45  

46cdef object _tensor_bridge = None 

47# Cache: type(obj) -> True/False for the torch tensor check. 

48# Once a type is seen, we never re-check. 

49cdef dict _torch_type_cache = {} 

50# Tri-state: None = not checked, True/False = result of version check 

51cdef object _torch_version_ok = None 

52  

53cdef inline bint _torch_version_check(): 

54 """Return True if 2.3 <= torch <= 2.12 (known AOTI ABI range). Memoized. 

55  

56 Lower bound: AOTI functions we use were introduced in PyTorch 2.3. 

57 Upper bound: the ``pyobj_to_aten_handle`` trick relies on the 

58 THPVariable struct layout (PyObject_HEAD followed by at::Tensor cdata) 

59 and the identity ``AtenTensorHandle == at::Tensor*``. Both are 

60 undocumented internals that could change in a future PyTorch version. 

61 We cap at the latest version we have tested against; unknown versions 

62 fall back to the standard DLPack/CAI paths. Bump the upper bound 

63 after verifying a new PyTorch release. 

64 """ 

65 global _torch_version_ok 

66 if _torch_version_ok is not None: 

67 return <bint>_torch_version_ok 

68 torch = sys.modules.get("torch") 

69 if torch is None: 

70 _torch_version_ok = False 

71 return False 

72 try: 

73 major, minor = int(torch.__version__.split(".")[0]), \ 

74 int(torch.__version__.split(".")[1]) 

75 _torch_version_ok = (2, 3) <= (major, minor) <= (2, 12) 

76 except (ValueError, IndexError): 

77 _torch_version_ok = False 

78 return <bint>_torch_version_ok 

79  

80  

81cdef inline bint _is_torch_tensor(object obj): 

82 cdef type tp = type(obj) 2^ ? @ ab% ( 4 2 6 1 7 8 9 ! # ) * + , - L N O M dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.bBb*bCb} ~ k cbZ _ 3 Y ` S T U V W X ] | Q R 5 [ i P I t u x y z E F G H A B C D v K J p f 0 ;bd e /bb j l q m n r h o g w c s a =b

83 cdef object cached = _torch_type_cache.get(tp) 2^ ? @ ab% ( 4 2 6 1 7 8 9 ! # ) * + , - L N O M dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.bBb*bCb} ~ k cbZ _ 3 Y ` S T U V W X ] | Q R 5 [ i P I t u x y z E F G H A B C D v K J p f 0 ;bd e /bb j l q m n r h o g w c s a =b

84 if cached is not None: 2^ ? @ ab% ( 4 2 6 1 7 8 9 ! # ) * + , - L N O M dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.bBb*bCb} ~ k cbZ _ 3 Y ` S T U V W X ] | Q R 5 [ i P I t u x y z E F G H A B C D v K J p f 0 ;bd e /bb j l q m n r h o g w c s a =b

85 return <bint>cached 2^ @ ab% ( 4 6 1 7 8 9 ! # ) * + , - N O M dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.b} ~ k Z _ 3 Y S T U V W X ] | Q R 5 [ i P I t u x y z E F G H A B C D v K J p f 0 ;bd e b j l q m n r h o g w c s a

86 cdef str mod = tp.__module__ or "" 2? % 2 6 1 L Bb*bCbk cb` f d e /bb j h g w a =b

87 cdef bint result = mod.startswith("torch") and hasattr(obj, "data_ptr") \ 2? % 2 6 1 L Bb*bCbk cb` f d e /bb j h g w a =b

88 and _torch_version_check() 

89 _torch_type_cache[tp] = result # setdefault not needed for bools 2? % 2 6 1 L Bb*bCbk cb` f d e /bb j h g w a =b

90 return result 2? % 2 6 1 L Bb*bCbk cb` f d e /bb j h g w a =b

91  

92  

93cdef object _get_tensor_bridge(): 

94 """Bootstrap AOTI symbols, then import _tensor_bridge on first use.""" 

95 global _tensor_bridge 

96 if _tensor_bridge is not None: 

97 return _tensor_bridge 

98 torch_C = sys.modules.get("torch._C") 

99 if torch_C is None: 

100 raise RuntimeError( 

101 "torch._C is not loaded; cannot initialise the tensor bridge. " 

102 "Make sure PyTorch is imported before passing a torch.Tensor.") 

103 ctypes.CDLL(torch_C.__file__, mode=ctypes.RTLD_GLOBAL) 

104 from cuda.core import _tensor_bridge as tb 

105 _tensor_bridge = tb 

106 return _tensor_bridge 

107  

108  

109try: 

110 from ml_dtypes import bfloat16 

111except ImportError: 

112 bfloat16 = None 

113  

114# TODO(leofang): support NumPy structured dtypes 

115  

116  

117cdef extern from "Python.h": 

118 ctypedef struct PyTypeObject: 

119 void* tp_dict 

120 void PyType_Modified(PyTypeObject*) 

121  

122  

123cdef DLPackExchangeAPI _SMV_DLPACK_EXCHANGE_API 

124cdef bint _SMV_DLPACK_EXCHANGE_API_INITED = False 

125_SMV_DLPACK_EXCHANGE_API_CAPSULE = cpython.PyCapsule_New( 

126 <void*>&_SMV_DLPACK_EXCHANGE_API, 

127 b"dlpack_exchange_api", 

128 NULL, 

129) 

130  

131  

132cdef class StridedMemoryView: 

133 """A class holding metadata of a strided dense array/tensor. 

134  

135 A :obj:`StridedMemoryView` instance can be created in three ways: 

136  

137 1. Using the :obj:`args_viewable_as_strided_memory` decorator (recommended) 

138 2. Explicit construction relying on DLPack or CUDA Array Interface, see below. 

139 3. From :obj:`~_memory.Buffer` and shape and size tuples (see 

140 :meth:`from_buffer` classmethod) 

141  

142 ``StridedMemoryView(obj, stream_ptr)`` can be used to create a view from 

143 objects supporting either DLPack (up to v1.0) or CUDA Array Interface 

144 (CAI) v3. When wrapping an arbitrary object it will try the DLPack protocol 

145 first, then the CAI protocol. A :obj:`BufferError` is raised if neither is 

146 supported. 

147  

148 Since either way would take a consumer stream, for DLPack it is passed to 

149 ``obj.__dlpack__()`` as-is (except for :obj:`None`, see below); for CAI, a 

150 stream order will be established between the consumer stream and the 

151 producer stream (from ``obj.__cuda_array_interface__()["stream"]``), as if 

152 ``cudaStreamWaitEvent`` is called by this method. 

153  

154 To opt-out of the stream ordering operation in either DLPack or CAI, 

155 please pass ``stream_ptr=-1``. Note that this deviates (on purpose) 

156 from the semantics of ``obj.__dlpack__(stream=None, ...)`` since ``cuda.core`` 

157 does not encourage using the (legacy) default/null stream, but is 

158 consistent with the CAI's semantics. For DLPack, ``stream=-1`` will be 

159 internally passed to ``obj.__dlpack__()`` instead. 

160  

161 Parameters 

162 ---------- 

163 obj : Any 

164 Any objects that supports either DLPack (up to v1.0) or CUDA Array 

165 Interface (v3). 

166 stream_ptr: int 

167 The pointer address (as Python `int`) to the **consumer** stream. 

168 Stream ordering will be properly established unless ``-1`` is passed. 

169  

170  

171 Attributes 

172 ----------- 

173 ptr : int 

174 Pointer to the tensor buffer (as a Python `int`). 

175 device_id : int 

176 The device ID for where the tensor is located. It is -1 for CPU tensors 

177 (meaning those only accessible from the host). 

178 is_device_accessible : bool 

179 Whether the tensor data can be accessed on the GPU. 

180 readonly: bool 

181 Whether the tensor data can be modified in place. 

182 exporting_obj : Any 

183 A reference to the original tensor object that is being viewed. 

184 If the view is created with :meth:`from_buffer`, 

185 it will be the Buffer instance passed to the method. 

186  

187 """ 

188 def __init__(self, obj: object = None, stream_ptr: int | None = None) -> None: 

189 cdef str clsname = self.__class__.__name__ 2. / : ; = @bEb

190 if obj is not None: 2. / : ; = @bEb

191 # populate self's attributes 

192 if check_has_dlpack(obj): 2. / : ; = Eb

193 warnings.warn( 1./:;=

194 f"Constructing a {clsname} directly from a DLPack-supporting object is deprecated; " 1./:;=

195 "Use `StridedMemoryView.from_dlpack` or `StridedMemoryView.from_any_interface` instead.", 

196 DeprecationWarning, 1./:;=

197 stacklevel=2, 

198 ) 

199 view_as_dlpack(obj, stream_ptr, self) 1./:;=

200 else: 

201 warnings.warn( 2Eb

202 f"Constructing a {clsname} directly from a CUDA-array-interface-supporting object is deprecated; " 2Eb

203 "Use `StridedMemoryView.from_cuda_array_interface` or `StridedMemoryView.from_any_interface` instead.", 

204 DeprecationWarning, 2Eb

205 stacklevel=2, 

206 ) 

207 view_as_cai(obj, stream_ptr, self) 2Eb

208 else: 

209 warnings.warn( 2@b

210 f"Constructing an empty {clsname} is deprecated; " 2@b

211 "use one of the classmethods `from_dlpack`, `from_cuda_array_interface` or `from_any_interface` " 

212 "to construct a StridedMemoryView from an object", 

213 DeprecationWarning, 2@b

214 stacklevel=2, 

215 ) 

216  

217 @classmethod 

218 def from_dlpack(cls, obj: object, stream_ptr: int | None=None) -> StridedMemoryView: 

219 """Create a view from an object supporting the `DLPack <https://dmlc.github.io/dlpack/latest/>`_ protocol. 

220  

221 Parameters 

222 ---------- 

223 obj : object 

224 An object implementing the `DLPack <https://dmlc.github.io/dlpack/latest/>`_ protocol 

225 (via ``__dlpack__``). 

226 stream_ptr : int, optional 

227 Stream pointer for synchronization. If ``None``, no synchronization is performed. 

228 """ 

229 cdef StridedMemoryView buf = StridedMemoryView.__new__(cls) 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 ;bd e /bb j l q m n r h o g w c s a =b

230 if _is_torch_tensor(obj): 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 ;bd e /bb j l q m n r h o g w c s a =b

231 _get_tensor_bridge().view_as_torch_tensor(obj, stream_ptr, buf) 

232 return buf 

233 view_as_dlpack(obj, stream_ptr, buf) 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 ;bd e /bb j l q m n r h o g w c s a =b

234 return buf 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

235  

236 @classmethod 

237 def from_cuda_array_interface(cls, obj: object, stream_ptr: int | None=None) -> StridedMemoryView: 

238 """Create a view from an object supporting the `__cuda_array_interface__ <https://numba.readthedocs.io/en/stable/cuda/cuda_array_interface.html>`_ protocol. 

239  

240 Parameters 

241 ---------- 

242 obj : object 

243 An object implementing the `__cuda_array_interface__ <https://numba.readthedocs.io/en/stable/cuda/cuda_array_interface.html>`_ protocol. 

244 stream_ptr : int, optional 

245 Stream pointer for synchronization. If ``None``, no synchronization is performed. 

246 """ 

247 cdef StridedMemoryView buf = StridedMemoryView.__new__(cls) 26 1 L Bb*bCbcb`

248 if _is_torch_tensor(obj): 26 1 L Bb*bCbcb`

249 _get_tensor_bridge().view_as_torch_tensor(obj, stream_ptr, buf) 

250 return buf 

251 view_as_cai(obj, stream_ptr, buf) 26 1 L Bb*bCbcb`

252 return buf 26 1 L BbCbcb`

253  

254 @classmethod 

255 def from_array_interface(cls, obj: object) -> StridedMemoryView: 

256 """Create a view from an object supporting the `__array_interface__ <https://numpy.org/doc/stable/reference/arrays.interface.html>`_ protocol. 

257  

258 Parameters 

259 ---------- 

260 obj : object 

261 An object implementing the `__array_interface__ <https://numpy.org/doc/stable/reference/arrays.interface.html>`_ protocol (e.g., a numpy array). 

262 """ 

263 cdef StridedMemoryView buf = StridedMemoryView.__new__(cls) 2dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.b] 5 P f d e

264 if _is_torch_tensor(obj): 2dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.b] 5 P f d e

265 _get_tensor_bridge().view_as_torch_tensor(obj, None, buf) 

266 return buf 

267 view_as_array_interface(obj, buf) 2dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.b] 5 P f d e

268 return buf 2dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb] 5 P f d e

269  

270 @classmethod 

271 def from_any_interface(cls, obj: object, stream_ptr: int | None = None) -> StridedMemoryView: 

272 """Create a view by automatically selecting the best available protocol. 

273  

274 Tries `DLPack <https://dmlc.github.io/dlpack/latest/>`_ first, then falls back to 

275 `__cuda_array_interface__ <https://numba.readthedocs.io/en/stable/cuda/cuda_array_interface.html>`_. 

276 ``torch.Tensor`` objects are transparently handled via a fast AOTI path 

277 regardless of which protocol is selected. 

278  

279 Parameters 

280 ---------- 

281 obj : object 

282 An object implementing `DLPack <https://dmlc.github.io/dlpack/latest/>`_ or 

283 `__cuda_array_interface__ <https://numba.readthedocs.io/en/stable/cuda/cuda_array_interface.html>`_. 

284 stream_ptr : int, optional 

285 Stream pointer for synchronization. If ``None``, no synchronization is performed. 

286 """ 

287 if check_has_dlpack(obj): 2^ ? @ ab% ( 4 2 6 1 ) * + , - {bN O M } ~ k Z _ 3 Y | Q R [ i I t u x y z E F G H A B C D v K J p b j l q m n r h o g w c s a

288 return cls.from_dlpack(obj, stream_ptr) 2^ ? @ ab% ( 4 2 ) * + , - N O M } ~ k Z _ 3 Y | Q R [ i I t u x y z E F G H A B C D v K J p b j l q m n r h o g w c s a

289 return cls.from_cuda_array_interface(obj, stream_ptr) 161

290  

291 @classmethod 

292 def from_buffer( 

293 cls, 

294 cyBuffer buffer not None : Buffer, 

295 shape : tuple[int, ...], 

296 strides : tuple[int, ...] | None = None, 

297 *, 

298 itemsize : int | None = None, 

299 dtype : numpy.dtype | None = None, 

300 is_readonly : bool = False 

301 ) -> StridedMemoryView: 

302 """ 

303 Creates a :obj:`StridedMemoryView` instance from a :obj:`~_memory.Buffer` and shape and strides tuples. 

304 The Buffer can be either allocation coming from a :obj:`MemoryResource` or an external allocation 

305 wrapped in a :obj:`~_memory.Buffer` object with ``Buffer.from_handle(ptr, size, owner=...)``. 

306  

307 .. caution:: 

308 When creating a :obj:`StridedMemoryView` from a :obj:`~_memory.Buffer`, 

309 no synchronization is performed. It is the user's responsibility to ensure 

310 the data in ``buffer`` is properly synchronized when consuming the view. 

311  

312 Parameters 

313 ---------- 

314 buffer : :obj:`~_memory.Buffer` 

315 The buffer to create the view from. 

316 shape : :obj:`tuple` 

317 The layout describing the shape, strides and itemsize of the elements in 

318 the buffer. 

319 strides : :obj:`tuple` 

320 The layout describing the shape, strides and itemsize of the elements in 

321 the buffer. 

322 dtype : :obj:`numpy.dtype` 

323 Optional dtype. 

324 If specified, the dtype's itemsize must match the layout's itemsize. 

325 is_readonly : bool, optional 

326 Whether the mark the view as readonly. 

327 """ 

328 cdef StridedMemoryView view = StridedMemoryView.__new__(cls) 2+b,b{ KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b?b^b[bFbGb:b-b$ bbDb'

329 if itemsize is None and dtype is None: 2+b,b{ KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b?b^b[bFbGb:b-b$ bbDb'

330 raise ValueError("Either itemsize or dtype must be specified") 2^b

331 if itemsize is not None and dtype is not None and itemsize != dtype.itemsize: 2+b,b{ KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b?b[bFbGb:b-b$ bbDb'

332 raise ValueError( 2[b

333 f"itemsize ({itemsize}) does not match dtype.itemsize ({dtype.itemsize})" 2[b

334 ) 

335 # (itemsize is None XOR dtype is None) OR they are equal 

336 view_buffer_strided( 2+b,b{ KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b?bFbGb:b-b$ bbDb'

337 view, 

338 buffer, 

339 _StridedLayout(shape=shape, strides=strides, itemsize=getattr(dtype, "itemsize", itemsize)), 2+b,b{ KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b?bFbGb:b-b$ bbDb'

340 dtype, 

341 is_readonly, 2+b,b{ KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b?bFbGb:b-b$ bbDb'

342 ) 

343 return view 2+b,b{ KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGb-b$ bbDb'

344  

345 def __dealloc__(self) -> None: 

346 if self.dl_tensor == NULL: 2+b,b^ ? @ ab% ( { 4 2 6 1 7 8 9 ! # ) * + , - . / : ; = L N O M dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.bKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b?b^b[bFbGb:b-bBb*bCb} ~ k $ @bEbcbbbZ _ 3 Y ` S T U V W X ] | Q R Db' )b5 [ HbIbJbP I t u x y z E F G H A B C D v K J p f 0 ;bd e /bb j l q m n r h o g w c s a =b

347 return 2+b,b{ 6 1 L N O M dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.bKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b?b^b[bFbGb:b-bBb*bCb$ @bEbcbbb_ 3 Y ` S T U V W X ] Db' 5 P f 0 ;bd e /bc =b

348  

349 if cpython.PyCapsule_IsValid( 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R )b[ HbIbJbI t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

350 self.metadata, DLPACK_VERSIONED_TENSOR_USED_NAME): 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R )b[ HbIbJbI t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

351 data = cpython.PyCapsule_GetPointer( 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R )b[ HbIbJbI t u x y z E F G H A B C D v K J p f 0 d e j l q m n r h o w c s a

352 self.metadata, DLPACK_VERSIONED_TENSOR_USED_NAME) 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R )b[ HbIbJbI t u x y z E F G H A B C D v K J p f 0 d e j l q m n r h o w c s a

353 dlm_tensor_ver = <DLManagedTensorVersioned*>data 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R )b[ HbIbJbI t u x y z E F G H A B C D v K J p f 0 d e j l q m n r h o w c s a

354 if dlm_tensor_ver.deleter != NULL: 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R )b[ HbIbJbI t u x y z E F G H A B C D v K J p f 0 d e j l q m n r h o w c s a

355 dlm_tensor_ver.deleter(dlm_tensor_ver) 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ I t u x y z E F G H A B C D v K J p f 0 d e j l q m n r h o c s a

356 elif cpython.PyCapsule_IsValid( 1bga

357 self.metadata, DLPACK_TENSOR_USED_NAME): 1bga

358 data = cpython.PyCapsule_GetPointer( 1bga

359 self.metadata, DLPACK_TENSOR_USED_NAME) 1bga

360 dlm_tensor = <DLManagedTensor*>data 1bga

361 if dlm_tensor.deleter != NULL: 1bga

362 dlm_tensor.deleter(dlm_tensor) 1ba

363  

364 def view( 

365 self, layout : _StridedLayout | None = None, dtype : numpy.dtype | None = None 

366 ) -> StridedMemoryView: 

367 """ 

368 Creates a new view with adjusted layout and dtype. 

369 Same as calling :meth:`from_buffer` with the current buffer. 

370 """ 

371 cdef StridedMemoryView view = StridedMemoryView.__new__(self.__class__) 2N O M FbGb_ 3 Y S T U V W X 0 c

372 if layout is None and dtype is None: 2N O M FbGb_ 3 Y S T U V W X 0 c

373 return self 1_

374 if layout is None: 2N O M FbGb3 Y S T U V W X 0 c

375 layout = self.get_layout() 1NOM3Y0c

376 if dtype is None: 2N O M FbGb3 Y S T U V W X 0 c

377 dtype = self.get_dtype() 2FbGbS T U V W X

378 view_buffer_strided(view, self.get_buffer(), layout, dtype, self.readonly) 2N O M FbGb3 Y S T U V W X 0 c

379 return view 2N O M FbGbY S T U V W X 0 c

380  

381 def as_tensor_map( 

382 self, 

383 box_dim: tuple[int, ...] | None = None, 

384 *, 

385 options: TensorMapDescriptorOptions | None = None, 

386 element_strides: tuple[int, ...] | None = None, 

387 data_type: object = None, 

388 interleave: object = None, 

389 swizzle: object = None, 

390 l2_promotion: object = None, 

391 oob_fill: object = None, 

392 ) -> object: 

393 """Create a tiled :obj:`TensorMapDescriptor` from this view. 

394  

395 This is the public entry point for creating tiled tensor map 

396 descriptors in ``cuda.core``. Pass either ``box_dim`` and the 

397 individual keyword arguments directly, or provide bundled tiled 

398 options via ``options=``. 

399 """ 

400 from cuda.core._tensor_map import TensorMapDescriptor 1({4261

401  

402 kwargs = {} 1({4261

403 if options is not None: 1({4261

404 kwargs["options"] = options 

405 if element_strides is not None: 1({4261

406 kwargs["element_strides"] = element_strides 1(42

407 if data_type is not None: 1({4261

408 kwargs["data_type"] = data_type 1(426

409 if interleave is not None: 1({4261

410 kwargs["interleave"] = interleave 1(

411 if swizzle is not None: 1({4261

412 kwargs["swizzle"] = swizzle 1(

413 if l2_promotion is not None: 1({4261

414 kwargs["l2_promotion"] = l2_promotion 1(

415 if oob_fill is not None: 1({4261

416 kwargs["oob_fill"] = oob_fill 1(

417 return TensorMapDescriptor._from_tiled(self, box_dim, **kwargs) 1({4261

418  

419 def copy_from( 

420 self, 

421 StridedMemoryView other not None: StridedMemoryView, 

422 stream: Stream | None, 

423 allocator: object = None, 

424 blocking: bool | None = None, 

425 ) -> None: 

426 """ 

427 Copies the data from the other view into this view. 

428  

429 The copy can be performed between following memory spaces: 

430 host-to-device, device-to-host, device-to-device (on the same device). 

431  

432 Parameters 

433 ---------- 

434 other : StridedMemoryView 

435 The view to copy data from. 

436 stream : Stream | None, optional 

437 The stream to schedule the copy on. 

438 allocator : MemoryResource | None, optional 

439 If temporary buffers are needed, the specified memory resources 

440 will be used to allocate the memory. If not specified, default 

441 resources will be used. 

442 blocking : bool | None, optional 

443 Whether the call should block until the copy is complete. 

444 * ``True``: the ``stream`` is synchronized with the host at the end of the call, 

445 blocking until the copy is complete. 

446 * ``False``: if possible, the call returns immediately once the copy is scheduled. 

447 However, in some cases of host-to-device or device-to-host copies, the call may 

448 still synchronize with the host if necessary. 

449 * ``None`` (default): 

450 * for device-to-device, it defaults to ``False`` (non-blocking), 

451 * for host-to-device or device-to-host, it defaults to ``True`` (blocking). 

452 """ 

453 raise NotImplementedError("Sorry, not supported: copy_from") 1}

454  

455 def copy_to( 

456 self, 

457 StridedMemoryView other not None: StridedMemoryView, 

458 stream: Stream | None = None, 

459 allocator: object = None, 

460 blocking: bool | None = None, 

461 ) -> None: 

462 """ 

463 Copies the data from this view into the ``other`` view. 

464  

465 For details, see :meth:`copy_from`. 

466 """ 

467 raise NotImplementedError("Sorry, not supported: copy_to") 1~

468  

469 def __dlpack__( 

470 self, 

471 *, 

472 stream: int | None = None, 

473 max_version: tuple[int, int] | None = None, 

474 dl_device: tuple[int, int] | None = None, 

475 copy: bool | None = None, 

476 ) -> object: 

477 # Similar to Buffer.__dlpack__: no implicit synchronization is performed. 

478 if dl_device is not None: 1@LNOMk$PItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

479 raise BufferError("Sorry, not supported: dl_device other than None") 1@

480 if copy is True: 1@LNOMk$PItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

481 raise BufferError("Sorry, not supported: copy=True") 1@

482  

483 cdef bint versioned 

484 if max_version is None: 1@LNOMk$PItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

485 versioned = False 1LNOM$Jbga

486 else: 

487 if not isinstance(max_version, tuple) or len(max_version) != 2: 1@kPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

488 raise BufferError(f"Expected max_version tuple[int, int], got {max_version}") 1@

489 versioned = max_version >= (1, 0) 1kPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

490  

491 # NOTE: stream is accepted for protocol compatibility but not used. 

492 cdef object capsule = _smv_make_py_capsule(self, versioned) 1LNOMk$PItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

493 return capsule 1LkPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

494  

495 def __dlpack_device__(self) -> tuple[int, int]: 

496 cdef _DLDeviceType device_type 

497 cdef int32_t device_id 

498 _smv_get_dl_device(self, &device_type, &device_id) 1^?{4261LkPfdebjlqmnrhogwcsa

499 return (<int>device_type, int(device_id)) 1^?{4261LkPfdebjlqmnrhogwcsa

500  

501 @property 

502 def _layout(self) -> _StridedLayout: 

503 """ 

504 The layout of the tensor. For StridedMemoryView created from DLPack or CAI, 

505 the layout is inferred from the tensor object's metadata. 

506 """ 

507 return self.get_layout() 2KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGb@bY S T U V W X

508  

509 @property 

510 def size(self) -> int: 

511 return self.get_layout().get_volume() 27 8 9 ! # ) * + , - . / : ; = dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmbBb

512  

513 @property 

514 def shape(self) -> tuple[int, ...]: 

515 """ 

516 Shape of the tensor. 

517 """ 

518 return self.get_layout().get_shape_tuple() 2+b,b% 7 8 9 ! # ) * + , - . / : ; = dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGbBbCbEbcbbbZ ` S T U V W X i b j c s

519  

520 @property 

521 def strides(self) -> tuple[int, ...] | None: 

522 """ 

523 Strides of the tensor (in **counts**, not bytes). 

524 """ 

525 return self.get_layout().get_strides_tuple() 2% 7 8 9 ! # ) * + , - . / : ; = dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bBbCbbbZ

526  

527 @property 

528 def dtype(self) -> numpy.dtype | None: 

529 """ 

530 Data type of the tensor. 

531  

532 Supports standard NumPy dtypes as well as narrow data types (e.g., ``bfloat16``) 

533 when the optional `ml_dtypes <https://github.com/jax-ml/ml_dtypes>`_ package is 

534 installed. If ``ml_dtypes`` is not available and such a tensor is encountered, 

535 a :obj:`NotImplementedError` will be raised. 

536 """ 

537 return self.get_dtype() 2dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b-bbbZ Y S T U V W X l q m n r h o

538  

539 def __repr__(self) -> str: 

540 return (f"StridedMemoryView(ptr={self.ptr},\n" 2bbZ

541 + f" shape={self.shape},\n" 2bbZ

542 + f" strides={self.strides},\n" 2bbZ

543 + f" itemsize={self._layout.itemsize},\n" 2bbZ

544 + f" dtype={get_simple_repr(self.dtype)},\n" 2bbZ

545 + f" device_id={self.device_id},\n" 2bbZ

546 + f" is_device_accessible={self.is_device_accessible},\n" 2bbZ

547 + f" readonly={self.readonly},\n" 2bbZ

548 + f" exporting_obj={get_simple_repr(self.exporting_obj)})") 2bbZ

549  

550 @cython.critical_section 

551 cdef inline _StridedLayout get_layout(self): 

552 cdef _StridedLayout layout 

553 if self._layout is None: 2+b,b% 4 2 6 1 7 8 9 ! # ) * + , - . / : ; = L N O M dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.bKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGbBb*bCbk $ @bEbcbbbZ 3 Y ` S T U V W X ] Q R Db' 5 i P I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

554 if self.dl_tensor: 2% 4 2 6 1 7 8 9 ! # ) * + , - . / : ; = L N O M dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.bBb*bCbk @bEbcbZ 3 Y ` S T U V W X ] Q R 5 i P I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

555 layout = layout_from_dlpack(self.dl_tensor) 1%42789!#)*+,-./:;=NOMkZ3YSTUVWXQRiItuxyzEFGHABCDvKJp0debjlqmnrhogwcsa

556 elif self.metadata is not None: 26 1 L dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.bBb*bCb@bEbcb` ] 5 P f d e

557 layout = layout_from_cai(self.metadata) 26 1 L dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.bBb*bCbEbcb` ] 5 P f d e

558 else: 

559 raise ValueError("Cannot infer layout from the exporting object") 2@b

560 if self._layout is None: 2% 4 2 6 1 7 8 9 ! # ) * + , - . / : ; = L N O M dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmbBbCbk EbcbZ 3 Y ` S T U V W X ] Q R 5 i P I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

561 self._layout = layout 2% 4 2 6 1 7 8 9 ! # ) * + , - . / : ; = L N O M dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmbBbCbk EbcbZ 3 Y ` S T U V W X ] Q R 5 i P I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

562 return self._layout 2+b,b% 4 2 6 1 7 8 9 ! # ) * + , - . / : ; = L N O M dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGbBbCbk $ EbcbbbZ 3 Y ` S T U V W X ] Q R Db' 5 i P I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

563  

564 @cython.critical_section 

565 cdef inline object get_buffer(self): 

566 """ 

567 Returns Buffer instance with the underlying data. 

568 If the SMV was created from a Buffer, it will return the same Buffer instance. 

569 Otherwise, it will create a new instance with owner set to the exporting object. 

570 """ 

571 cdef object buffer 

572 if self._buffer is None: 2{ 6 1 L N O M FbGb3 Y S T U V W X 0 c

573 if isinstance(self.exporting_obj, Buffer): 161LNOM3YSTUVWX0c

574 buffer = self.exporting_obj 10

575 else: 

576 buffer = Buffer.from_handle(self.ptr, 0, owner=self.exporting_obj) 161LNOM3YSTUVWXc

577 if self._buffer is None: 161LNOM3YSTUVWX0c

578 self._buffer = buffer 161LNOM3YSTUVWX0c

579 return self._buffer 2{ 6 1 L N O M FbGb3 Y S T U V W X 0 c

580  

581 @cython.critical_section 

582 cdef inline object get_dtype(self): 

583 cdef object dtype 

584 if self._dtype is None: 2{ 1 L N O M dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGb-bk $ bbZ Y S T U V W X ] Q R Db' 5 i P I t u x y z E F G H A B C D v K J p f d e b j l q m n r h o g w c s a

585 dtype = None 2{ 1 L dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmbk $ bbZ S T U V W X ] Q R Db' 5 i P I t u x y z E F G H A B C D v K J p f d e b j l q m n r h o g w c s a

586 if self.dl_tensor != NULL: 2{ 1 L dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmbk $ bbZ S T U V W X ] Q R Db' 5 i P I t u x y z E F G H A B C D v K J p f d e b j l q m n r h o g w c s a

587 dtype = dtype_dlpack_to_numpy(&self.dl_tensor.dtype) 1kZSTUVWXQRiItuxyzEFGHABCDvKJpdebjlqmnrhogwcsa

588 elif isinstance(self.metadata, int): 2{ 1 L dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb$ bb] Db' 5 P f d e

589 # AOTI dtype code stored by the torch tensor bridge 

590 dtype = _get_tensor_bridge().resolve_aoti_dtype( 

591 self.metadata) 

592 elif self.metadata is not None: 2{ 1 L dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb$ bb] Db' 5 P f d e

593 dtype = _typestr2dtype(self.metadata["typestr"]) 21 L dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb] 5 P f d e

594 if self._dtype is None: 2{ 1 L dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmbk $ bbZ S T U V W X ] Q R Db' 5 i P I t u x y z E F G H A B C D v K J p f d e b j l q m n r h o g w c s a

595 self._dtype = dtype 2{ 1 L dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmbk $ bbZ S T U V W X ] Q R Db' 5 i P I t u x y z E F G H A B C D v K J p f d e b j l q m n r h o g w c s a

596 return self._dtype 2{ 1 L N O M dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmbKbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGb-bk $ bbZ Y S T U V W X ] Q R Db' 5 i P I t u x y z E F G H A B C D v K J p f d e b j l q m n r h o g w c s a

597  

598  

599cdef void _smv_pycapsule_deleter(object capsule) noexcept: 

600 cdef DLManagedTensor* dlm_tensor 

601 cdef DLManagedTensorVersioned* dlm_tensor_ver 

602 # Do not invoke the deleter on a used capsule. 

603 if cpython.PyCapsule_IsValid(capsule, DLPACK_TENSOR_UNUSED_NAME): 2L k )bHbIbJbP I t u x y z E F G H A B C D v K J p f d e b j l q m n r h o c s a

604 dlm_tensor = <DLManagedTensor*>( 1LJ

605 cpython.PyCapsule_GetPointer(capsule, DLPACK_TENSOR_UNUSED_NAME) 1LJ

606 ) 

607 if dlm_tensor.deleter: 1LJ

608 dlm_tensor.deleter(dlm_tensor) 1LJ

609 elif cpython.PyCapsule_IsValid(capsule, DLPACK_VERSIONED_TENSOR_UNUSED_NAME): 2k )bHbIbJbP I t u x y z E F G H A B C D v K p f d e b j l q m n r h o c s a

610 dlm_tensor_ver = <DLManagedTensorVersioned*>( 1p

611 cpython.PyCapsule_GetPointer(capsule, DLPACK_VERSIONED_TENSOR_UNUSED_NAME) 1p

612 ) 

613 if dlm_tensor_ver.deleter: 1p

614 dlm_tensor_ver.deleter(dlm_tensor_ver) 1p

615  

616  

617cdef inline void _smv_release_export_resources(void* manager_ctx, int64_t* shape_ptr) noexcept with gil: 

618 if shape_ptr: 1LNOMk$'5PItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

619 stdlib.free(shape_ptr) 1LkPItuxyzEFGHABCDvJpfdebjlqmnrhogwcsa

620 if manager_ctx: 1LNOMk$'5PItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

621 cpython.Py_DECREF(<object>manager_ctx) 1LNOMk$'5PItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

622  

623  

624cdef void _smv_deleter(DLManagedTensor* tensor) noexcept with gil: 

625 if tensor: 1LNOM$Jbga

626 _smv_release_export_resources(tensor.manager_ctx, tensor.dl_tensor.shape) 1LNOM$Jbga

627 tensor.manager_ctx = NULL 1LNOM$Jbga

628 stdlib.free(tensor) 1LNOM$Jbga

629  

630  

631cdef void _smv_versioned_deleter(DLManagedTensorVersioned* tensor) noexcept with gil: 

632 if tensor: 1NOMk$'5PItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

633 _smv_release_export_resources(tensor.manager_ctx, tensor.dl_tensor.shape) 1k'5PItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

634 tensor.manager_ctx = NULL 1k'5PItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

635 stdlib.free(tensor) 1k'5PItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

636  

637  

638cdef inline DLManagedTensorVersioned* _smv_allocate_dlm_tensor_versioned() except? NULL: 

639 cdef DLManagedTensorVersioned* dlm_tensor_ver = NULL 1k'5iPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

640 dlm_tensor_ver = <DLManagedTensorVersioned*>stdlib.malloc(sizeof(DLManagedTensorVersioned)) 1k'5iPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

641 if dlm_tensor_ver == NULL: 1k'5iPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

642 raise MemoryError() 

643 dlm_tensor_ver.dl_tensor.shape = NULL 1k'5iPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

644 dlm_tensor_ver.manager_ctx = NULL 1k'5iPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

645 return dlm_tensor_ver 1k'5iPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

646  

647  

648cdef inline DLManagedTensor* _smv_allocate_dlm_tensor() except? NULL: 

649 cdef DLManagedTensor* dlm_tensor = NULL 1LNOM$Jbga

650 dlm_tensor = <DLManagedTensor*>stdlib.malloc(sizeof(DLManagedTensor)) 1LNOM$Jbga

651 if dlm_tensor == NULL: 1LNOM$Jbga

652 raise MemoryError() 

653 dlm_tensor.dl_tensor.shape = NULL 1LNOM$Jbga

654 dlm_tensor.manager_ctx = NULL 1LNOM$Jbga

655 return dlm_tensor 1LNOM$Jbga

656  

657  

658cdef inline int _smv_dtype_numpy_to_dlpack(object dtype_obj, DLDataType* out_dtype) except -1: 

659 cdef object np_dtype = numpy.dtype(dtype_obj) 1LNOMk]QR5iPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

660 if np_dtype.fields is not None: 1LNOMk]QR5iPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

661 raise BufferError("Structured dtypes are not supported for DLPack export") 1O

662 if not np_dtype.isnative and np_dtype.byteorder not in ("=", "|"): 1LNMk]QR5iPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

663 raise BufferError("Non-native-endian dtypes are not supported for DLPack export") 1N]5

664  

665 cdef str kind = np_dtype.kind 1LMkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

666 cdef int bits = np_dtype.itemsize * 8 1LMkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

667 cdef uint8_t code 

668 if kind == "b": 1LMkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

669 if bits != 8: 1I

670 raise BufferError(f"Unsupported bool dtype itemsize: {np_dtype.itemsize}") 

671 code = <uint8_t>kDLBool 1I

672 elif kind == "i": 1LMkQRiPtuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

673 if bits not in (8, 16, 32, 64): 1kQRPEFGHJpfbjlqmnrhogwcsa

674 raise BufferError(f"Unsupported signed integer dtype: {np_dtype}") 

675 code = <uint8_t>kDLInt 1kQRPEFGHJpfbjlqmnrhogwcsa

676 elif kind == "u": 1LMituxyzABCDvKde

677 if bits not in (8, 16, 32, 64): 1ABCD

678 raise BufferError(f"Unsupported unsigned integer dtype: {np_dtype}") 

679 code = <uint8_t>kDLUInt 1ABCD

680 elif kind == "f": 1LMituxyzvKde

681 if bits not in (16, 32, 64): 1Lixyzde

682 raise BufferError(f"Unsupported floating dtype: {np_dtype}") 

683 code = <uint8_t>kDLFloat 1Lixyzde

684 elif kind == "c": 1MtuvK

685 if bits not in (64, 128): 1tuvK

686 raise BufferError(f"Unsupported complex dtype: {np_dtype}") 

687 code = <uint8_t>kDLComplex 1tuvK

688 else: 

689 raise BufferError(f"Unsupported dtype for DLPack export: {np_dtype}") 1M

690  

691 out_dtype.code = code 1LkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

692 out_dtype.bits = <uint8_t>bits 1LkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

693 out_dtype.lanes = <uint16_t>1 1LkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

694 return 0 1LkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

695  

696  

697cdef inline int _smv_get_dl_device( 

698 StridedMemoryView view, 

699 _DLDeviceType* out_device_type, 

700 int32_t* out_device_id, 

701) except -1: 

702 cdef _DLDeviceType device_type 

703 cdef int32_t device_id 

704 cdef object buf 

705 if view.dl_tensor != NULL: 1^?{4261LkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

706 device_type = view.dl_tensor.device.device_type 1^?42kQRiItuxyzEFGHABCDvKJpdebjlqmnrhogwcsa

707 if device_type == _kDLCUDA: 1^?42kQRiItuxyzEFGHABCDvKJpdebjlqmnrhogwcsa

708 device_id = view.dl_tensor.device.device_id 142

709 else: 

710 # CPU, CUDAHost, and CUDAManaged use device_id=0 in DLPack. 

711 device_id = 0 1^?kQRiItuxyzEFGHABCDvKJpdebjlqmnrhogwcsa

712 elif view.is_device_accessible: 1{61LPfde

713 buf = view.get_buffer() 1{61L

714 dev_type, dev_id = classify_dl_device(buf) 1{61L

715 device_type = <_DLDeviceType>dev_type 1{61L

716 device_id = <int32_t>dev_id 1{61L

717 else: 

718 device_type = _kDLCPU 1Pfde

719 device_id = 0 1Pfde

720  

721 out_device_type[0] = device_type 1^?{4261LkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

722 out_device_id[0] = device_id 1^?{4261LkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

723 return 0 1^?{4261LkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

724  

725  

726cdef inline int _smv_setup_dl_tensor_common( 

727 DLTensor* dl_tensor, 

728 StridedMemoryView view, 

729 _StridedLayout layout, 

730) except -1: 

731 cdef object dtype_obj = view.get_dtype() 2L N O M k $ ] Q R Db' 5 i P I t u x y z E F G H A B C D v K J p f d e b j l q m n r h o g w c s a

732 if dtype_obj is None: 2L N O M k $ ] Q R Db' 5 i P I t u x y z E F G H A B C D v K J p f d e b j l q m n r h o g w c s a

733 raise BufferError( 2$ Db'

734 "Cannot export StridedMemoryView via DLPack without dtype information; " 

735 "create the view with dtype specified." 

736 ) 

737 _smv_dtype_numpy_to_dlpack(dtype_obj, &dl_tensor.dtype) 1LNOMk]QR5iPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

738 _smv_get_dl_device(view, &dl_tensor.device.device_type, &dl_tensor.device.device_id) 1LkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

739  

740 cdef int ndim = layout.base.ndim 1LkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

741 dl_tensor.ndim = ndim 1LkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

742 if layout.get_volume() == 0: 1LkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

743 dl_tensor.data = NULL 1v

744 else: 

745 dl_tensor.data = <void*><intptr_t>view.ptr 1LkQRiPItuxyzEFGHABCDKJpfdebjlqmnrhogwcsa

746 dl_tensor.byte_offset = 0 1LkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

747 return 0 1LkQRiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

748  

749  

750cdef inline int _smv_setup_dl_tensor(DLTensor* dl_tensor, StridedMemoryView view) except -1: 

751 cdef _StridedLayout layout = view.get_layout() 1LNOMk$'5iPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

752 _smv_setup_dl_tensor_common(dl_tensor, view, layout) 1LNOMk$'5iPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

753  

754 cdef int i 

755 cdef int64_t* shape_strides = NULL 1LkiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

756 cdef int64_t* strides_src = NULL 1LkiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

757 cdef int ndim = dl_tensor.ndim 1LkiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

758 if ndim == 0: 1LkiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

759 dl_tensor.shape = NULL 1K

760 dl_tensor.strides = NULL 1K

761 else: 

762 # DLPack v1.2+ requires non-NULL strides for ndim != 0. 

763 shape_strides = <int64_t*>stdlib.malloc(sizeof(int64_t) * 2 * ndim) 1LkiPItuxyzEFGHABCDvJpfdebjlqmnrhogwcsa

764 if shape_strides == NULL: 1LkiPItuxyzEFGHABCDvJpfdebjlqmnrhogwcsa

765 raise MemoryError() 

766 try: 1LkiPItuxyzEFGHABCDvJpfdebjlqmnrhogwcsa

767 strides_src = get_strides_ptr(layout.base) 1LkiPItuxyzEFGHABCDvJpfdebjlqmnrhogwcsa

768 for i in range(ndim): 1LkiPItuxyzEFGHABCDvJpfdebjlqmnrhogwcsa

769 shape_strides[i] = layout.base.shape[i] 1LkiPItuxyzEFGHABCDvJpfdebjlqmnrhogwcsa

770 shape_strides[i + ndim] = strides_src[i] 1LkiPItuxyzEFGHABCDvJpfdebjlqmnrhogwcsa

771 except Exception: 

772 stdlib.free(shape_strides) 

773 raise 

774 dl_tensor.shape = shape_strides 1LkiPItuxyzEFGHABCDvJpfdebjlqmnrhogwcsa

775 dl_tensor.strides = shape_strides + ndim 1LkiPItuxyzEFGHABCDvJpfdebjlqmnrhogwcsa

776 return 0 1LkiPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

777  

778  

779cdef inline int _smv_setup_dltensor_borrowed(DLTensor* dl_tensor, StridedMemoryView view) except -1: 

780 cdef _StridedLayout layout = view.get_layout() 2] Q R Db

781 _smv_setup_dl_tensor_common(dl_tensor, view, layout) 2] Q R Db

782  

783 if dl_tensor.ndim == 0: 1QR

784 dl_tensor.shape = NULL 1Q

785 dl_tensor.strides = NULL 1Q

786 else: 

787 dl_tensor.shape = layout.base.shape 1R

788 # For temporary/non-owning exchange we provide explicit strides. 

789 dl_tensor.strides = get_strides_ptr(layout.base) 1R

790 return 0 1QR

791  

792  

793cdef inline int _smv_fill_managed_tensor_versioned( 

794 DLManagedTensorVersioned* dlm_tensor_ver, 

795 StridedMemoryView view, 

796) except -1: 

797 cpython.Py_INCREF(view) 1k'5iPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

798 dlm_tensor_ver.manager_ctx = <void*>view 1k'5iPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

799 dlm_tensor_ver.deleter = _smv_versioned_deleter 1k'5iPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

800 dlm_tensor_ver.version.major = DLPACK_MAJOR_VERSION 1k'5iPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

801 dlm_tensor_ver.version.minor = DLPACK_MINOR_VERSION 1k'5iPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

802 dlm_tensor_ver.flags = DLPACK_FLAG_BITMASK_READ_ONLY if view.readonly else 0 1k'5iPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

803 _smv_setup_dl_tensor(&dlm_tensor_ver.dl_tensor, view) 1k'5iPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

804 return 0 1kiPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

805  

806  

807cdef inline int _smv_fill_managed_tensor( 

808 DLManagedTensor* dlm_tensor, 

809 StridedMemoryView view, 

810) except -1: 

811 cpython.Py_INCREF(view) 1LNOM$Jbga

812 dlm_tensor.manager_ctx = <void*>view 1LNOM$Jbga

813 dlm_tensor.deleter = _smv_deleter 1LNOM$Jbga

814 _smv_setup_dl_tensor(&dlm_tensor.dl_tensor, view) 1LNOM$Jbga

815 return 0 1LJbga

816  

817  

818cdef object _smv_make_py_capsule(StridedMemoryView view, bint versioned): 

819 cdef DLManagedTensor* dlm_tensor = NULL 1LNOMk$PItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

820 cdef DLManagedTensorVersioned* dlm_tensor_ver = NULL 1LNOMk$PItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

821 cdef object capsule = None 1LNOMk$PItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

822 cdef void* tensor_ptr = NULL 1LNOMk$PItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

823 cdef const char* capsule_name 

824 try: 1LNOMk$PItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

825 if versioned: 1LNOMk$PItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

826 dlm_tensor_ver = _smv_allocate_dlm_tensor_versioned() 1kPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

827 _smv_fill_managed_tensor_versioned(dlm_tensor_ver, view) 1kPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

828 tensor_ptr = <void*>dlm_tensor_ver 1kPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

829 capsule_name = DLPACK_VERSIONED_TENSOR_UNUSED_NAME 1kPItuxyzEFGHABCDvKpfdebjlqmnrhowcsa

830 else: 

831 dlm_tensor = _smv_allocate_dlm_tensor() 1LNOM$Jbga

832 _smv_fill_managed_tensor(dlm_tensor, view) 1LNOM$Jbga

833 tensor_ptr = <void*>dlm_tensor 1LJbga

834 capsule_name = DLPACK_TENSOR_UNUSED_NAME 1LJbga

835 capsule = cpython.PyCapsule_New(tensor_ptr, capsule_name, _smv_pycapsule_deleter) 1LkPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

836 except Exception: 1NOM$

837 if capsule is None: 1NOM$

838 _smv_deleter(dlm_tensor) 1NOM$

839 _smv_versioned_deleter(dlm_tensor_ver) 1NOM$

840 raise 1NOM$

841 return capsule 1LkPItuxyzEFGHABCDvKJpfdebjlqmnrhogwcsa

842  

843  

844cdef inline StridedMemoryView _smv_from_dlpack_capsule(object capsule, object exporting_obj): 

845 cdef void* data = NULL 2)bi HbIbJb

846 cdef DLTensor* dl_tensor = NULL 2)bi HbIbJb

847 cdef DLManagedTensorVersioned* dlm_tensor_ver = NULL 2)bi HbIbJb

848 cdef DLManagedTensor* dlm_tensor = NULL 2)bi HbIbJb

849 cdef bint is_readonly = False 2)bi HbIbJb

850 cdef const char* used_name = NULL 2)bi HbIbJb

851 if cpython.PyCapsule_IsValid(capsule, DLPACK_VERSIONED_TENSOR_UNUSED_NAME): 2)bi HbIbJb

852 data = cpython.PyCapsule_GetPointer(capsule, DLPACK_VERSIONED_TENSOR_UNUSED_NAME) 2)bi HbIbJb

853 dlm_tensor_ver = <DLManagedTensorVersioned*>data 2)bi HbIbJb

854 dl_tensor = &dlm_tensor_ver.dl_tensor 2)bi HbIbJb

855 is_readonly = bool((dlm_tensor_ver.flags & DLPACK_FLAG_BITMASK_READ_ONLY) != 0) 2)bi HbIbJb

856 used_name = DLPACK_VERSIONED_TENSOR_USED_NAME 2)bi HbIbJb

857 elif cpython.PyCapsule_IsValid(capsule, DLPACK_TENSOR_UNUSED_NAME): 

858 data = cpython.PyCapsule_GetPointer(capsule, DLPACK_TENSOR_UNUSED_NAME) 

859 dlm_tensor = <DLManagedTensor*>data 

860 dl_tensor = &dlm_tensor.dl_tensor 

861 is_readonly = False 

862 used_name = DLPACK_TENSOR_USED_NAME 

863 else: 

864 raise BufferError("Invalid DLPack capsule") 

865  

866 cpython.PyCapsule_SetName(capsule, used_name) 2)bi HbIbJb

867  

868 cdef StridedMemoryView view = StridedMemoryView.__new__(StridedMemoryView) 2)bi HbIbJb

869 view.dl_tensor = dl_tensor 2)bi HbIbJb

870 view.metadata = capsule 2)bi HbIbJb

871 view.ptr = <intptr_t>(dl_tensor.data) + <intptr_t>(dl_tensor.byte_offset) 2)bi HbIbJb

872 view.readonly = is_readonly 2)bi HbIbJb

873 view.exporting_obj = exporting_obj 2)bi HbIbJb

874 if dl_tensor.device.device_type == _kDLCPU: 2)bi HbIbJb

875 view.device_id = -1 1i

876 view.is_device_accessible = False 1i

877 elif dl_tensor.device.device_type in (_kDLCUDA, _kDLCUDAHost, _kDLCUDAManaged): 2Hb

878 view.device_id = dl_tensor.device.device_id 2HbIbJb

879 view.is_device_accessible = True 2HbIbJb

880 else: 

881 raise BufferError("device not supported") 2)b

882 return view 2i HbIbJb

883  

884  

885cdef int _smv_managed_tensor_allocator( 

886 DLTensor* prototype, 

887 DLManagedTensorVersioned** out, 

888 void* error_ctx, 

889 void (*SetError)(void* error_ctx, const char* kind, const char* message) noexcept, 

890) noexcept with gil: 

891 if out != NULL: 2_b

892 out[0] = NULL 2_b

893 if SetError != NULL: 2_b

894 SetError(error_ctx, b"NotImplementedError", b"managed_tensor_allocator is not supported by StridedMemoryView") 

895 cpython.PyErr_SetString(NotImplementedError, b"managed_tensor_allocator is not supported by StridedMemoryView") 2_b

896 return -1 2_b

897  

898  

899cdef int _smv_managed_tensor_from_py_object_no_sync( 

900 void* py_object, 

901 DLManagedTensorVersioned** out, 

902) except -1 with gil: 

903 cdef DLManagedTensorVersioned* dlm_tensor_ver = NULL 1'5[i

904 if out == NULL: 1'5[i

905 raise RuntimeError("out cannot be NULL") 1[

906 out[0] = NULL 1'5[i

907 cdef object obj = <object>py_object 1'5[i

908 if not isinstance(obj, StridedMemoryView): 1'5[i

909 raise TypeError("py_object must be a StridedMemoryView") 1[

910 try: 1'5i

911 dlm_tensor_ver = _smv_allocate_dlm_tensor_versioned() 1'5i

912 _smv_fill_managed_tensor_versioned(dlm_tensor_ver, <StridedMemoryView>obj) 1'5i

913 except BaseException: 1'5

914 # Rollback must also run for KeyboardInterrupt. 

915 _smv_versioned_deleter(dlm_tensor_ver) 1'5

916 raise 1'5

917 out[0] = dlm_tensor_ver 1i

918 return 0 1i

919  

920  

921cdef int _smv_managed_tensor_to_py_object_no_sync( 

922 DLManagedTensorVersioned* tensor, 

923 void** out_py_object, 

924) except -1 with gil: 

925 if out_py_object == NULL: 2)bi HbIbJbgc|b

926 raise RuntimeError("out_py_object cannot be NULL") 2gc

927 out_py_object[0] = NULL 2)bi HbIbJb|b

928 if tensor == NULL: 2)bi HbIbJb|b

929 raise RuntimeError("tensor cannot be NULL") 2|b

930 cdef object capsule = cpython.PyCapsule_New( 2)bi HbIbJb

931 <void*>tensor, 

932 DLPACK_VERSIONED_TENSOR_UNUSED_NAME, 

933 _smv_pycapsule_deleter, 

934 ) 

935 cdef object py_view = _smv_from_dlpack_capsule(capsule, capsule) 2)bi HbIbJb

936 cpython.Py_INCREF(py_view) 2i HbIbJb

937 out_py_object[0] = <void*>py_view 2i HbIbJb

938 return 0 2i HbIbJb

939  

940  

941cdef int _smv_dltensor_from_py_object_no_sync( 

942 void* py_object, 

943 DLTensor* out, 

944) except -1 with gil: 

945 if out == NULL: 2] | Q }bR Db

946 raise RuntimeError("out cannot be NULL") 1|

947 cdef object obj = <object>py_object 2] Q }bR Db

948 if not isinstance(obj, StridedMemoryView): 2] Q }bR Db

949 raise TypeError("py_object must be a StridedMemoryView") 2}b

950 _smv_setup_dltensor_borrowed(out, <StridedMemoryView>obj) 2] Q R Db

951 return 0 1QR

952  

953  

954cdef int _smv_current_work_stream( 

955 _DLDeviceType device_type, 

956 int32_t device_id, 

957 void** out_current_stream, 

958) except -1 with gil: 

959 if out_current_stream == NULL: 2hcbc

960 raise RuntimeError("out_current_stream cannot be NULL") 2hc

961 # cuda.core has no global/current stream state today. 

962 out_current_stream[0] = NULL 2bc

963 return 0 2bc

964  

965  

966cdef void _init_smv_dlpack_exchange_api(): 

967 global _SMV_DLPACK_EXCHANGE_API_INITED 

968 if _SMV_DLPACK_EXCHANGE_API_INITED: 

969 return 

970 _SMV_DLPACK_EXCHANGE_API.header.version.major = DLPACK_MAJOR_VERSION 

971 _SMV_DLPACK_EXCHANGE_API.header.version.minor = DLPACK_MINOR_VERSION 

972 _SMV_DLPACK_EXCHANGE_API.header.prev_api = NULL 

973 _SMV_DLPACK_EXCHANGE_API.managed_tensor_allocator = _smv_managed_tensor_allocator 

974 _SMV_DLPACK_EXCHANGE_API.managed_tensor_from_py_object_no_sync = _smv_managed_tensor_from_py_object_no_sync 

975 _SMV_DLPACK_EXCHANGE_API.managed_tensor_to_py_object_no_sync = _smv_managed_tensor_to_py_object_no_sync 

976 _SMV_DLPACK_EXCHANGE_API.dltensor_from_py_object_no_sync = _smv_dltensor_from_py_object_no_sync 

977 _SMV_DLPACK_EXCHANGE_API.current_work_stream = _smv_current_work_stream 

978 _SMV_DLPACK_EXCHANGE_API_INITED = True 

979  

980  

981_init_smv_dlpack_exchange_api() 

982# cdef classes are immutable types in Cython 3, so inject these attributes 

983# directly into the type dict. 

984(<dict>(<PyTypeObject*>StridedMemoryView).tp_dict)["__dlpack_c_exchange_api__"] = _SMV_DLPACK_EXCHANGE_API_CAPSULE 

985(<dict>(<PyTypeObject*>StridedMemoryView).tp_dict)["__c_dlpack_exchange_api__"] = _SMV_DLPACK_EXCHANGE_API_CAPSULE 

986PyType_Modified(<PyTypeObject*>StridedMemoryView) 

987  

988  

989cdef str get_simple_repr(obj): 

990 # TODO: better handling in np.dtype objects 

991 cdef object obj_class 

992 cdef str obj_repr 

993 if isinstance(obj, type): 2bbZ

994 obj_class = obj 

995 else: 

996 obj_class = obj.__class__ 2bbZ

997 if obj_class.__module__ in (None, "builtins"): 2bbZ

998 obj_repr = obj_class.__name__ 2bb

999 else: 

1000 obj_repr = f"{obj_class.__module__}.{obj_class.__name__}" 2bbZ

1001 return obj_repr 2bbZ

1002  

1003  

1004  

1005cdef bint check_has_dlpack(obj) except*: 

1006 cdef bint has_dlpack 

1007 if hasattr(obj, "__dlpack__") and hasattr(obj, "__dlpack_device__"): 2^ ? @ ab% ( 4 2 6 1 7 8 9 ! # ) * + , - . / : ; = {bN O M } ~ k Eb]bcbZ _ 3 Y | Q R [ i I t u x y z E F G H A B C D v K J p b j l q m n r h o g w c s a

1008 has_dlpack = True 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y | Q R [ i I t u x y z E F G H A B C D v K J p b j l q m n r h o g w c s a

1009 elif hasattr(obj, "__cuda_array_interface__"): 26 1 {bEb]bcb

1010 has_dlpack = False 26 1 Eb]bcb

1011 else: 

1012 raise BufferError( 2{b

1013 "the input object does not support any data exchange protocol") 

1014 return has_dlpack 2^ ? @ ab% ( 4 2 6 1 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Eb]bcbZ _ 3 Y | Q R [ i I t u x y z E F G H A B C D v K J p b j l q m n r h o g w c s a

1015  

1016  

1017cdef class _StridedMemoryViewProxy: 

1018 cdef readonly: 

1019 object obj 

1020 bint has_dlpack 

1021  

1022 def __init__(self, obj: object) -> None: 

1023 self.obj = obj 27 8 9 ! # ]bcb

1024 self.has_dlpack = check_has_dlpack(obj) 27 8 9 ! # ]bcb

1025  

1026 cpdef StridedMemoryView view(self, stream_ptr=None): 

1027 if self.has_dlpack: 27 8 9 ! # cb

1028 return StridedMemoryView.from_dlpack(self.obj, stream_ptr) 1789!#

1029 else: 

1030 return StridedMemoryView.from_cuda_array_interface(self.obj, stream_ptr) 2cb

1031  

1032  

1033cdef StridedMemoryView view_as_dlpack(obj, stream_ptr, view=None): 

1034 cdef int dldevice, device_id 

1035 cdef bint is_device_accessible, is_readonly = False 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 ;bd e /bb j l q m n r h o g w c s a =b

1036 is_device_accessible = False 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 ;bd e /bb j l q m n r h o g w c s a =b

1037 dldevice, device_id = obj.__dlpack_device__() 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 ;bd e /bb j l q m n r h o g w c s a =b

1038 if dldevice == _kDLCPU: 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 ;bd e /bb j l q m n r h o g w c s a =b

1039 assert device_id == 0 2@ ab% ( 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f ;bb j l q m n r h o g w c s a

1040 device_id = -1 2@ ab% ( 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f ;bb j l q m n r h o g w c s a

1041 if stream_ptr is None: 2@ ab% ( 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f ;bb j l q m n r h o g w c s a

1042 raise BufferError("stream=None is ambiguous with view()") 2;b

1043 elif stream_ptr == -1: 2@ ab% ( 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f b j l q m n r h o g w c s a

1044 stream_ptr = None 2@ ab% ( 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f b j l q m n r h o g w c s a

1045 elif dldevice == _kDLCUDA: 

1046 assert device_id >= 0 24 2 0 /b

1047 is_device_accessible = True 24 2 0 /b

1048 # no need to check other stream values, it's a pass-through 

1049 if stream_ptr is None: 24 2 0 /b

1050 raise BufferError("stream=None is ambiguous with view()") 2/b

1051 elif dldevice in (_kDLCUDAHost, _kDLCUDAManaged): 1d

1052 is_device_accessible = True 1^?de

1053 # just do a pass-through without any checks, as pinned/managed memory can be 

1054 # accessed on both host and device 

1055 else: 

1056 raise BufferError("device not supported") 2=b

1057  

1058 cdef object capsule 

1059 try: 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1060 capsule = obj.__dlpack__( 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1061 stream=int(stream_ptr) if stream_ptr else None, 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1062 max_version=(DLPACK_MAJOR_VERSION, DLPACK_MINOR_VERSION)) 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1063 except TypeError: 1bga

1064 capsule = obj.__dlpack__( 1bga

1065 stream=int(stream_ptr) if stream_ptr else None) 1bga

1066  

1067 cdef void* data = NULL 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1068 cdef DLTensor* dl_tensor = NULL 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1069 cdef DLManagedTensorVersioned* dlm_tensor_ver 

1070 cdef DLManagedTensor* dlm_tensor 

1071 cdef const char *used_name = NULL 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1072 if cpython.PyCapsule_IsValid( 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1073 capsule, DLPACK_VERSIONED_TENSOR_UNUSED_NAME): 

1074 data = cpython.PyCapsule_GetPointer( 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1075 capsule, DLPACK_VERSIONED_TENSOR_UNUSED_NAME) 

1076 dlm_tensor_ver = <DLManagedTensorVersioned*>data 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1077 dl_tensor = &dlm_tensor_ver.dl_tensor 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1078 is_readonly = bool((dlm_tensor_ver.flags & DLPACK_FLAG_BITMASK_READ_ONLY) != 0) 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1079 used_name = DLPACK_VERSIONED_TENSOR_USED_NAME 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1080 elif cpython.PyCapsule_IsValid( 1bga

1081 capsule, DLPACK_TENSOR_UNUSED_NAME): 

1082 data = cpython.PyCapsule_GetPointer( 1bga

1083 capsule, DLPACK_TENSOR_UNUSED_NAME) 

1084 dlm_tensor = <DLManagedTensor*>data 1bga

1085 dl_tensor = &dlm_tensor.dl_tensor 1bga

1086 is_readonly = False 1bga

1087 used_name = DLPACK_TENSOR_USED_NAME 1bga

1088 else: 

1089 assert False 

1090  

1091 cpython.PyCapsule_SetName(capsule, used_name) 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1092  

1093 cdef StridedMemoryView buf = StridedMemoryView() if view is None else view 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1094 buf.dl_tensor = dl_tensor 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1095 buf.metadata = capsule 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1096 buf.ptr = <intptr_t>(dl_tensor.data) + <intptr_t>(dl_tensor.byte_offset) 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1097 buf.device_id = device_id 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1098 buf.is_device_accessible = is_device_accessible 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1099 buf.readonly = is_readonly 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1100 buf.exporting_obj = obj 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1101  

1102 return buf 2^ ? @ ab% ( 4 2 7 8 9 ! # ) * + , - . / : ; = N O M } ~ k Z _ 3 Y S T U V W X | Q R [ i I t u x y z E F G H A B C D v K J p f 0 d e b j l q m n r h o g w c s a

1103  

1104  

1105@functools.lru_cache 

1106def _typestr2dtype(str typestr) -> numpy.dtype: 

1107 return numpy.dtype(typestr) 2L dbebfbgbhbibjbkblbmbBbCb]

1108  

1109  

1110@functools.lru_cache 

1111def _typestr2itemsize(str typestr) -> int: 

1112 return _typestr2dtype(typestr).itemsize 2L dbebfbgbhbibjbkblbmbBbCb]

1113  

1114  

1115cdef object dtype_dlpack_to_numpy(DLDataType* dtype): 

1116 cdef int bits = dtype.bits 1kZSTUVWXQRiItuxyzEFGHABCDvKJpdebjlqmnrhogwcsa

1117 if dtype.lanes != 1: 1kZSTUVWXQRiItuxyzEFGHABCDvKJpdebjlqmnrhogwcsa

1118 # TODO: return a NumPy structured dtype? 

1119 raise NotImplementedError( 1h

1120 f'vector dtypes (lanes={dtype.lanes}) is not supported') 1h

1121 if dtype.code == kDLUInt: 1kZSTUVWXQRiItuxyzEFGHABCDvKJpdebjlqmnrhogwcsa

1122 if bits == 8: 1ABCDo

1123 np_dtype = numpy.uint8 1A

1124 elif bits == 16: 

1125 np_dtype = numpy.uint16 1B

1126 elif bits == 32: 

1127 np_dtype = numpy.uint32 1C

1128 elif bits == 64: 

1129 np_dtype = numpy.uint64 1D

1130 else: 

1131 raise TypeError('uint{} is not supported.'.format(bits)) 1o

1132 elif dtype.code == kDLInt: 

1133 if bits == 8: 1kZSTUVWXQREFGHJpbjlqmnrhogwcsa

1134 np_dtype = numpy.int8 1E

1135 elif bits == 16: 

1136 np_dtype = numpy.int16 1QF

1137 elif bits == 32: 

1138 np_dtype = numpy.int32 1kZSTUVWXRGJpbjlqmnrhogwcsa

1139 elif bits == 64: 

1140 np_dtype = numpy.int64 1H

1141 else: 

1142 raise TypeError('int{} is not supported.'.format(bits)) 1r

1143 elif dtype.code == kDLFloat: 

1144 if bits == 16: 1ixyzden

1145 np_dtype = numpy.float16 1x

1146 elif bits == 32: 

1147 np_dtype = numpy.float32 1yde

1148 elif bits == 64: 

1149 np_dtype = numpy.float64 1iz

1150 else: 

1151 raise TypeError('float{} is not supported.'.format(bits)) 1n

1152 elif dtype.code == kDLComplex: 

1153 # TODO(leofang): support complex32 

1154 if bits == 64: 1tuvKm

1155 np_dtype = numpy.complex64 1t

1156 elif bits == 128: 

1157 np_dtype = numpy.complex128 1uvK

1158 else: 

1159 raise TypeError('complex{} is not supported.'.format(bits)) 1m

1160 elif dtype.code == kDLBool: 

1161 if bits == 8: 1Il

1162 np_dtype = numpy.bool_ 1I

1163 else: 

1164 raise TypeError(f'{bits}-bit bool is not supported') 1l

1165 elif dtype.code == kDLBfloat: 

1166 if bfloat16 is not None: 

1167 np_dtype = numpy.dtype("bfloat16") 

1168 else: 

1169 raise NotImplementedError( 

1170 'Support for bfloat16 within cuda-core requires `ml_dtypes`' 

1171 'to be installed.' 

1172 ) 

1173 else: 

1174 raise TypeError('Unsupported dtype. dtype code: {}'.format(dtype.code)) 1q

1175  

1176 # We want the dtype object not just the type object 

1177 return numpy.dtype(np_dtype) 1kZSTUVWXQRiItuxyzEFGHABCDvKJpdebjlqmnrhogwcsa

1178  

1179  

1180cpdef StridedMemoryView view_as_cai(obj, stream_ptr, view=None): 

1181 cdef dict cai_data = obj.__cuda_array_interface__ 26 1 ~b`bccdcL Bb*bCbEbcb`

1182 if cai_data.get("version", 0) < 3: 26 1 ~b`bccdcL Bb*bCbEbcb`

1183 raise BufferError("only CUDA Array Interface v3 or above is supported") 2ccdc

1184 if cai_data.get("mask") is not None: 26 1 ~b`bL Bb*bCbEbcb`

1185 raise BufferError("mask is not supported") 2~b

1186 if stream_ptr is None: 26 1 `bL Bb*bCbEbcb`

1187 raise BufferError("stream=None is ambiguous with view()") 2`b

1188  

1189 cdef StridedMemoryView buf = StridedMemoryView() if view is None else view 26 1 L Bb*bCbEbcb`

1190 buf.exporting_obj = obj 26 1 L Bb*bCbEbcb`

1191 buf.metadata = cai_data 26 1 L Bb*bCbEbcb`

1192 buf.dl_tensor = NULL 26 1 L Bb*bCbEbcb`

1193 # Validate shape/strides/typestr eagerly so constructor paths fail fast. 

1194 buf.get_layout() 26 1 L Bb*bCbEbcb`

1195 buf.ptr, buf.readonly = cai_data["data"] 26 1 L BbCbEbcb`

1196 buf.is_device_accessible = True 26 1 L BbCbEbcb`

1197 if buf.ptr != 0: 26 1 L BbCbEbcb`

1198 buf.device_id = handle_return( 161L`

1199 driver.cuPointerGetAttribute( 161L`

1200 driver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL, 161L`

1201 buf.ptr)) 161L`

1202 else: 

1203 buf.device_id = handle_return(driver.cuCtxGetDevice()) 2BbCbEbcb

1204  

1205 cdef intptr_t producer_s, consumer_s 

1206 cdef EventHandle h_event 

1207 stream_ptr = int(stream_ptr) 26 1 L BbCbEbcb`

1208 if stream_ptr != -1: 26 1 L BbCbEbcb`

1209 stream = cai_data.get("stream") 1`

1210 if stream is not None: 1`

1211 producer_s = <intptr_t>(stream) 1`

1212 consumer_s = <intptr_t>(stream_ptr) 1`

1213 assert producer_s > 0 1`

1214 # establish stream order 

1215 if producer_s != consumer_s: 1`

1216 with nogil: 1`

1217 # The event must belong to the producer stream's context to 

1218 # be recorded on it, whatever context is current here. 

1219 h_event = create_event_handle_for_stream( 1`

1220 <cydriver.CUstream>producer_s, cydriver.CUevent_flags.CU_EVENT_DISABLE_TIMING) 

1221 if not h_event: 1`

1222 HANDLE_RETURN(get_last_error()) 

1223 HANDLE_RETURN(cydriver.cuEventRecord( 1`

1224 as_cu(h_event), <cydriver.CUstream>producer_s)) 

1225 HANDLE_RETURN(cydriver.cuStreamWaitEvent( 1`

1226 <cydriver.CUstream>consumer_s, as_cu(h_event), 0)) 

1227 elif _is_torch_tensor(obj): 

1228 # PyTorch's __cuda_array_interface__ reports version 2 and 

1229 # omits the "stream" field, so the standard CAI sync path 

1230 # above is a no-op for torch tensors. This is unsafe: the 

1231 # consumer has no guarantee that the producer's work is 

1232 # visible. We fix this by querying PyTorch's current CUDA 

1233 # stream via the AOTI stable C ABI and performing the same 

1234 # event-based stream ordering. 

1235 _get_tensor_bridge().sync_torch_stream( 

1236 buf.device_id, <intptr_t>(stream_ptr)) 

1237  

1238 return buf 26 1 L BbCbEbcb`

1239  

1240  

1241cpdef StridedMemoryView view_as_array_interface(obj, view=None): 

1242 cdef dict data = obj.__array_interface__ 2acecfcdbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.b] 5 P f d e

1243 if data.get("version", 0) < 3: 2acecfcdbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.b] 5 P f d e

1244 raise BufferError("only NumPy Array Interface v3 or above is supported") 2ecfc

1245 if data.get("mask") is not None: 2acdbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.b] 5 P f d e

1246 raise BufferError("mask is not supported") 2ac

1247  

1248 cdef StridedMemoryView buf = StridedMemoryView() if view is None else view 2dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.b] 5 P f d e

1249 buf.exporting_obj = obj 2dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.b] 5 P f d e

1250 buf.metadata = data 2dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.b] 5 P f d e

1251 buf.dl_tensor = NULL 2dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.b] 5 P f d e

1252 # Validate shape/strides/typestr eagerly so constructor paths fail fast. 

1253 buf.get_layout() 2dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.b] 5 P f d e

1254 buf.ptr, buf.readonly = data["data"] 2dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb] 5 P f d e

1255 buf.is_device_accessible = False 2dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb] 5 P f d e

1256 buf.device_id = -1 2dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb] 5 P f d e

1257 return buf 2dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb] 5 P f d e

1258  

1259  

1260def args_viewable_as_strided_memory(arg_indices: tuple[int, ...]) -> Callable[[Callable[..., Any]], Callable[..., Any]]: 

1261 """ 

1262 Decorator to create proxy objects to :obj:`StridedMemoryView` for the 

1263 specified positional arguments. 

1264  

1265 This allows array/tensor attributes to be accessed inside the function 

1266 implementation, while keeping the function body array-library-agnostic (if 

1267 desired). 

1268  

1269 Inside the decorated function, the specified arguments become instances 

1270 of an (undocumented) proxy type, regardless of its original source. A 

1271 :obj:`StridedMemoryView` instance can be obtained by passing the (consumer) 

1272 stream pointer (as a Python `int`) to the proxies's ``view()`` method. For 

1273 example: 

1274  

1275 .. code-block:: python 

1276  

1277 @args_viewable_as_strided_memory((1,)) 

1278 def my_func(arg0, arg1, arg2, stream: Stream): 

1279 # arg1 can be any object supporting DLPack or CUDA Array Interface 

1280 view = arg1.view(stream.handle) 

1281 assert isinstance(view, StridedMemoryView) 

1282 ... 

1283  

1284 Parameters 

1285 ---------- 

1286 arg_indices : tuple 

1287 The indices of the target positional arguments. 

1288 """ 

1289 def wrapped_func_with_indices(func: "Callable") -> "Callable": 1789!#

1290 @functools.wraps(func) 1789!#

1291 def wrapped_func(*args, **kwargs) -> object: 

1292 args = list(args) 1789!#

1293 cdef int idx 

1294 for idx in arg_indices: 1789!#

1295 args[idx] = _StridedMemoryViewProxy(args[idx]) 1789!#

1296 return func(*args, **kwargs) 1789!#

1297 return wrapped_func 1789!#

1298 return wrapped_func_with_indices 1789!#

1299  

1300  

1301cdef inline _StridedLayout layout_from_dlpack(DLTensor* dl_tensor): 

1302 cdef _StridedLayout layout = _StridedLayout.__new__(_StridedLayout) 1%42789!#)*+,-./:;=NOMkZ3YSTUVWXQRiItuxyzEFGHABCDvKJp0debjlqmnrhogwcsa

1303 cdef int nbits = dl_tensor.dtype.bits * dl_tensor.dtype.lanes 1%42789!#)*+,-./:;=NOMkZ3YSTUVWXQRiItuxyzEFGHABCDvKJp0debjlqmnrhogwcsa

1304 cdef int itemsize = nbits >> 3 1%42789!#)*+,-./:;=NOMkZ3YSTUVWXQRiItuxyzEFGHABCDvKJp0debjlqmnrhogwcsa

1305 if (itemsize << 3) != nbits: 1%42789!#)*+,-./:;=NOMkZ3YSTUVWXQRiItuxyzEFGHABCDvKJp0debjlqmnrhogwcsa

1306 raise ValueError("dl_tensor.dtype.bits must be a multiple of 8") 1s

1307 layout.init_from_ptr(dl_tensor.ndim, dl_tensor.shape, dl_tensor.strides, itemsize) 1%42789!#)*+,-./:;=NOMkZ3YSTUVWXQRiItuxyzEFGHABCDvKJp0debjlqmnrhogwcsa

1308 return layout 1%42789!#)*+,-./:;=NOMkZ3YSTUVWXQRiItuxyzEFGHABCDvKJp0debjlqmnrhogwcsa

1309  

1310  

1311cdef _StridedLayout layout_from_cai(object metadata): 

1312 cdef _StridedLayout layout = _StridedLayout.__new__(_StridedLayout) 26 1 L dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.bBb*bCbEbcb` ] 5 P f d e

1313 cdef object shape = metadata["shape"] 26 1 L dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.bBb*bCbEbcb` ] 5 P f d e

1314 cdef object strides = metadata.get("strides") 26 1 L dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.bBb*bCbEbcb` ] 5 P f d e

1315 cdef int itemsize = _typestr2itemsize(metadata["typestr"]) 26 1 L dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.bBb*bCbEbcb` ] 5 P f d e

1316 layout.init_from_tuple(shape, strides, itemsize, True) 26 1 L dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmb.bBb*bCbEbcb` ] 5 P f d e

1317 return layout 26 1 L dbebnbfbobgbhbibjbkbpbqbrbsbtbubvbwbxbybzblbAbmbBbCbEbcb` ] 5 P f d e

1318  

1319  

1320cdef inline intptr_t get_data_ptr(object buffer, _StridedLayout layout) except? 0: 

1321 return <intptr_t>(int(buffer.handle)) + layout.get_slice_offset_in_bytes() 2+b,b{ N O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGb-b$ bbY S T U V W X Db' 0 c

1322  

1323  

1324cdef inline int view_buffer_strided( 

1325 StridedMemoryView view, 

1326 object buffer, 

1327 _StridedLayout layout, 

1328 object dtype, 

1329 bint is_readonly, 

1330) except -1: 

1331 if isinstance(buffer, Buffer): 2+b,b{ N O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b?bFbGb:b-b$ bb3 Y S T U V W X Db' 0 c

1332 Buffer_check_open(<cyBuffer>buffer) 2+b,b{ N O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b?bFbGb:b-b$ bb3 Y S T U V W X Db' 0 c

1333 if dtype is not None: 2+b,b{ N O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b?bFbGb:b-b$ bb3 Y S T U V W X Db' 0 c

1334 dtype = numpy.dtype(dtype) 2+b,bN O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b?bFbGb:b-b3 Y S T U V W X 0 c

1335 if dtype.itemsize != layout.itemsize: 2+b,bN O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b?bFbGb:b-b3 Y S T U V W X 0 c

1336 raise ValueError( 13

1337 f"The dtype's itemsize ({dtype.itemsize}) does not match the layout's " 13

1338 f"itemsize ({layout.itemsize})." 13

1339 ) 

1340 # Check the layout's offset range [min_offset, max_offset] fits 

1341 # within the [0, buffer.size - 1] range. 

1342 # The required_size_in_bytes fails if min_offset < 0. 

1343 # NB. For external memory, both positive and negative offsets can be valid, 

1344 # but for a proper check we'd need to know both size and data offset, 

1345 # while neither is reported by the packages. 

1346 cdef bint is_allocated = buffer.memory_resource is not None 2+b,b{ N O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b?bFbGb:b-b$ bbY S T U V W X Db' 0 c

1347 if is_allocated and buffer.size < layout.get_required_size_in_bytes(): 2+b,b{ N O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(b?bFbGb:b-b$ bbY S T U V W X Db' 0 c

1348 raise ValueError( 2:b

1349 f"Buffer size is too small for the layout. " 2:b

1350 f"Expected at least {layout.get_required_size_in_bytes()} bytes, " 2:b

1351 f"got {buffer.size} bytes." 2:b

1352 ) 

1353 # set the public attributes 

1354 view.ptr = get_data_ptr(buffer, layout) 2+b,b{ N O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGb-b$ bbY S T U V W X Db' 0 c

1355 view.device_id = buffer.device_id 2+b,b{ N O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGb-b$ bbY S T U V W X Db' 0 c

1356 view.is_device_accessible = buffer.is_device_accessible 2+b,b{ N O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGb-b$ bbY S T U V W X Db' 0 c

1357 view.readonly = is_readonly 2+b,b{ N O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGb-b$ bbY S T U V W X Db' 0 c

1358 view.exporting_obj = view._buffer = buffer 2+b,b{ N O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGb-b$ bbY S T U V W X Db' 0 c

1359 # no dlpack/cai metadata 

1360 view.dl_tensor = NULL 2+b,b{ N O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGb-b$ bbY S T U V W X Db' 0 c

1361 view.metadata = None 2+b,b{ N O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGb-b$ bbY S T U V W X Db' 0 c

1362 # we get the layout from the caller 

1363 view._layout = layout 2+b,b{ N O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGb-b$ bbY S T U V W X Db' 0 c

1364 view._dtype = dtype 2+b,b{ N O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGb-b$ bbY S T U V W X Db' 0 c

1365 return 0 2+b,b{ N O M KbLbMbNbObPbQbRbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(bFbGb-b$ bbY S T U V W X Db' 0 c