Coverage for cuda/core/_memory/_buffer.pyx: 88.84%

215 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-07-19 01:12 +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 libc.stdint cimport uintptr_t 

9from libcpp.atomic cimport memory_order_acquire, memory_order_release 

10  

11from cuda.bindings cimport cydriver 

12from cuda.core._memory._device_memory_resource import DeviceMemoryResource 

13from cuda.core._memory._pinned_memory_resource import PinnedMemoryResource 

14from cuda.core._memory._ipc cimport IPCBufferDescriptor, IPCDataForBuffer 

15from cuda.core._memory cimport _ipc 

16from cuda.core._resource_handles cimport ( 

17 DevicePtrHandle, 

18 StreamHandle, 

19 deviceptr_create_with_owner, 

20 deviceptr_create_with_mr, 

21 register_mr_dealloc_callback, 

22 as_intptr, 

23 as_cu, 

24 set_deallocation_stream, 

25) 

26from cuda.core.typing import DevicePointerType 

27  

28from cuda.core._stream cimport Stream, Stream_accept, default_stream 

29from cuda.core._utils.cuda_utils cimport HANDLE_RETURN, _parse_fill_value 

30  

31import sys 

32from typing import TYPE_CHECKING 

33  

34from cuda.core._utils.pycompat import BufferProtocol 

35from cuda.core._dlpack import classify_dl_device, make_py_capsule 

36from cuda.core._device import Device 

37  

38if TYPE_CHECKING: 

39 from cuda.core.graph import GraphBuilder 

40  

41  

42# ============================================================================= 

43# MR deallocation callback (invoked from C++ shared_ptr deleter) 

44# ============================================================================= 

45  

46cdef void _mr_dealloc_callback( 

47 object mr, 

48 cydriver.CUdeviceptr ptr, 

49 size_t size, 

50 const StreamHandle& h_stream, 

51) noexcept: 

52 """Called by the C++ deleter to deallocate via MemoryResource.deallocate. 

53  

54 This is the C++ teardown path: there is no Python caller frame from 

55 which to obtain a stream. If the device-pointer handle was created 

56 without ``set_deallocation_stream`` being called (e.g. buffers minted 

57 via ``Buffer.from_handle(ptr, size, mr=mr)`` from DLPack import, 

58 third-party adapters, or other foreign sources), ``h_stream`` is 

59 empty here. Stream-ordered MR ``deallocate`` overrides reject 

60 ``stream=None`` (issue #2001), so without a fallback the destructor 

61 would print a warning and leak the allocation. Fall back to the 

62 legacy/per-thread default stream so the free still happens; this is 

63 the unique exception to the "no implicit default-stream fallback" 

64 policy because the teardown has no other source of truth. 

65 """ 

66 cdef Stream stream 

67 try: 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 | } ~ abpbqbrbsbtbubvbR S T -f.f/f:f;fSc=f?f@fbb[f]f{ {f|fDbEbFbcbGbHbebfblbmbgbhbcede}fa b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bW X VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIc3d_ ee{cfe/c@c[cOcPcNcQcd e f

68 stream = Stream._from_handle(Stream, h_stream) if h_stream else default_stream() 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 | } ~ abpbqbrbsbtbubvbR S T -f.f/f:f;fSc=f?f@fbb[f]f{ {f|fDbEbFbcbGbHbebfblbmbgbhbcede}fa b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bW X VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIc3d_ ee{cfe/c@c[cOcPcNcQcd e f

69 mr.deallocate(int(ptr), size, stream=stream) 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 | } ~ abpbqbrbsbtbubvbR S T -f.f/f:f;fSc=f?f@fbb[f]f{ {f|fDbEbFbcbGbHbebfblbmbgbhbcede}fa b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bW X VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIc3d_ ee{cfe/c@c[cOcPcNcQcd e f

70 except Exception as exc: 2Nc

71 print(f"Warning: mr.deallocate() failed during Buffer destruction: {exc}", 2Nc

72 file=sys.stderr) 2Nc

73  

74register_mr_dealloc_callback(_mr_dealloc_callback) 

75  

76  

77__all__ = ['Buffer', 'MemoryResource'] 

78  

79  

80# Memory Attribute Query Helpers 

81# ------------------------------ 

82cdef inline int _query_memory_attrs( 

83 _MemAttrs& out, 

84 cydriver.CUdeviceptr ptr 

85) except -1 nogil: 

86 """Query memory attributes for a device pointer.""" 

87 cdef unsigned int memory_type = 0 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbU V dbAbBbW X Y Z _ jbobCbd e f ` JbKbLbMbNbObPbQbRbSb

88 cdef int is_managed = 0 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbU V dbAbBbW X Y Z _ jbobCbd e f ` JbKbLbMbNbObPbQbRbSb

89 cdef int device_id = 0 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbU V dbAbBbW X Y Z _ jbobCbd e f ` JbKbLbMbNbObPbQbRbSb

90 cdef cydriver.CUpointer_attribute[3] attrs = [ 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbU V dbAbBbW X Y Z _ jbobCbd e f ` JbKbLbMbNbObPbQbRbSb

91 cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_MEMORY_TYPE, 

92 cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_IS_MANAGED, 

93 cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL, 

94 ] 

95 cdef uintptr_t[3] vals = [ 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbU V dbAbBbW X Y Z _ jbobCbd e f ` JbKbLbMbNbObPbQbRbSb

96 <uintptr_t><void*>&memory_type, 

97 <uintptr_t><void*>&is_managed, 

98 <uintptr_t><void*>&device_id, 

99 ] 

100  

101 cdef cydriver.CUresult ret 

102 ret = cydriver.cuPointerGetAttributes(3, attrs, <void**>vals, ptr) 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbU V dbAbBbW X Y Z _ jbobCbd e f ` JbKbLbMbNbObPbQbRbSb

103 if ret == cydriver.CUresult.CUDA_ERROR_NOT_INITIALIZED: 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbU V dbAbBbW X Y Z _ jbobCbd e f ` JbKbLbMbNbObPbQbRbSb

104 with cython.gil: 

105 # Device class handles the cuInit call internally 

106 Device() 

107 ret = cydriver.cuPointerGetAttributes(3, attrs, <void**>vals, ptr) 

108 HANDLE_RETURN(ret) 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbU V dbAbBbW X Y Z _ jbobCbd e f ` JbKbLbMbNbObPbQbRbSb

109  

110 # TODO: HMM/ATS-enabled sysmem should also report is_managed=True; the 

111 # CU_POINTER_ATTRIBUTE_IS_MANAGED query does not capture that yet. 

112 out.is_managed = is_managed != 0 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbU V dbAbBbW X Y Z _ jbobCbd e f ` JbKbLbMbNbObPbQbRbSb

113  

114 if memory_type == 0: 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbU V dbAbBbW X Y Z _ jbobCbd e f ` JbKbLbMbNbObPbQbRbSb

115 # unregistered host pointer 

116 out.is_host_accessible = True 2dbY Z JbKbLbMbNbObPbQbRbSb

117 out.is_device_accessible = False 2dbY Z JbKbLbMbNbObPbQbRbSb

118 out.device_id = -1 2dbY Z JbKbLbMbNbObPbQbRbSb

119 elif ( 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbU V AbBbW X Y Z _ jbobCbd e f `

120 is_managed 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbU V AbBbW X Y Z _ jbobCbd e f `

121 or memory_type == cydriver.CUmemorytype.CU_MEMORYTYPE_HOST 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T { a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibU V W X Y Z obCbd e f `

122 ): 

123 # Managed memory or pinned host memory 

124 out.is_host_accessible = True 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzba b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbAbBbW X Y Z _ jbCbd e f

125 out.is_device_accessible = True 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzba b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbAbBbW X Y Z _ jbCbd e f

126 out.device_id = device_id 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzba b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbAbBbW X Y Z _ jbCbd e f

127 elif memory_type == cydriver.CUmemorytype.CU_MEMORYTYPE_DEVICE: 2{ U V ob`

128 out.is_host_accessible = False 2{ U V ob`

129 out.is_device_accessible = True 2{ U V ob`

130 out.device_id = device_id 2{ U V ob`

131 else: 

132 with cython.gil: 

133 raise ValueError(f"Unsupported memory type: {memory_type}") 

134 return 0 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbU V dbAbBbW X Y Z _ jbobCbd e f ` JbKbLbMbNbObPbQbRbSb

135  

136  

137cdef inline void _init_memory_attrs(Buffer self): 

138 """Initialize memory attributes by querying the pointer.""" 

139 if not self._mem_attrs_inited.load(memory_order_acquire): 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbU V dbAbBbW X Y Z _ jbobCbd e f ` JbKbLbMbNbObPbQbRbSb

140 _query_memory_attrs(self._mem_attrs, as_cu(self._h_ptr)) 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbU V dbAbBbW X Y Z _ jbobCbd e f ` JbKbLbMbNbObPbQbRbSb

141 self._mem_attrs_inited.store(True, memory_order_release) 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnbU V dbAbBbW X Y Z _ jbobCbd e f ` JbKbLbMbNbObPbQbRbSb

142  

143  

144cdef class Buffer: 

145 """Represent a handle to allocated memory. 

146  

147 This generic object provides a unified representation for how 

148 different memory resources are to give access to their memory 

149 allocations. 

150  

151 Support for data interchange mechanisms are provided by DLPack. 

152  

153 Note 

154 ---- 

155 Pickling an IPC-enabled :class:`Buffer` embeds an 

156 :class:`~_memory.IPCBufferDescriptor`. Unpickling reconstructs the buffer 

157 by calling :meth:`from_ipc_descriptor` and therefore performs an IPC 

158 import. Do not unpickle buffers from untrusted sources. 

159 """ 

160 def __cinit__(self) -> None: 

161 self._clear() 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K CdDd4d7f8fEd:cFdGd;c=cDfHdId5dJdKdL M N O P Q 0 6d7d8d9f!f#f| } ~ abpbqbrbsbtbubvb^e_e`epdqdrdR S T Ibwbmeneoepeqe9dScre$fxbse%fte'fbbueveybzb!d#d$d%d'd{ 7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb{e|ecede,d(fTd-d~cldadUdfdgdhdmda b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIcndodKc3d_ jb}cLc}e~eaf.d/d:d;d=d?d@d[d]d^d_d`d{didee{cfe/cobCbjd]cMc?ckd@c[cOcPcNcQcd e f ,eRcEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZf0f1f2f3fdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAfbdcdbfcf4f5f[e]e)f*fsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud` JbKbLbwexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf+f,f2e3eCf4e5e6eMb6fNbObPbQbRbSb

162  

163 def _clear(self) -> None: 

164 self._h_ptr.reset() # Release the handle 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K CdDd4d7f8fEd:cFdGd;c=cDfHdId5dJdKdL M N O P Q 0 6d7d8d9f!f#f| } ~ abpbqbrbsbtbubvb^e_e`epdqdrdR S T Ibwbmeneoepeqe9dScre$fxbse%fte'fbbueveybzb!d#d$d%d'd{ 7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb{e|ecede,d(fTd-d~cldadUdfdgdhdmda b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIcndodKc3d_ jb}cLc}e~eaf.d/d:d;d=d?d@d[d]d^d_d`d{didee{cfe/cobCbjd]cMc?ckd@c[cOcPcNcQcd e f ,eRcEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZf0f1f2f3fdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAfbdcdbfcf4f5f[e]e)f*fsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud` JbKbLbwexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf+f,f2e3eCf4e5e6eMb6fNbObPbQbRbSb

165 self._size = 0 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K CdDd4d7f8fEd:cFdGd;c=cDfHdId5dJdKdL M N O P Q 0 6d7d8d9f!f#f| } ~ abpbqbrbsbtbubvb^e_e`epdqdrdR S T Ibwbmeneoepeqe9dScre$fxbse%fte'fbbueveybzb!d#d$d%d'd{ 7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb{e|ecede,d(fTd-d~cldadUdfdgdhdmda b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIcndodKc3d_ jb}cLc}e~eaf.d/d:d;d=d?d@d[d]d^d_d`d{didee{cfe/cobCbjd]cMc?ckd@c[cOcPcNcQcd e f ,eRcEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZf0f1f2f3fdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAfbdcdbfcf4f5f[e]e)f*fsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud` JbKbLbwexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf+f,f2e3eCf4e5e6eMb6fNbObPbQbRbSb

166 self._memory_resource = None 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K CdDd4d7f8fEd:cFdGd;c=cDfHdId5dJdKdL M N O P Q 0 6d7d8d9f!f#f| } ~ abpbqbrbsbtbubvb^e_e`epdqdrdR S T Ibwbmeneoepeqe9dScre$fxbse%fte'fbbueveybzb!d#d$d%d'd{ 7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb{e|ecede,d(fTd-d~cldadUdfdgdhdmda b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIcndodKc3d_ jb}cLc}e~eaf.d/d:d;d=d?d@d[d]d^d_d`d{didee{cfe/cobCbjd]cMc?ckd@c[cOcPcNcQcd e f ,eRcEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZf0f1f2f3fdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAfbdcdbfcf4f5f[e]e)f*fsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud` JbKbLbwexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf+f,f2e3eCf4e5e6eMb6fNbObPbQbRbSb

167 self._ipc_data = None 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K CdDd4d7f8fEd:cFdGd;c=cDfHdId5dJdKdL M N O P Q 0 6d7d8d9f!f#f| } ~ abpbqbrbsbtbubvb^e_e`epdqdrdR S T Ibwbmeneoepeqe9dScre$fxbse%fte'fbbueveybzb!d#d$d%d'd{ 7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb{e|ecede,d(fTd-d~cldadUdfdgdhdmda b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIcndodKc3d_ jb}cLc}e~eaf.d/d:d;d=d?d@d[d]d^d_d`d{didee{cfe/cobCbjd]cMc?ckd@c[cOcPcNcQcd e f ,eRcEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZf0f1f2f3fdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAfbdcdbfcf4f5f[e]e)f*fsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud` JbKbLbwexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf+f,f2e3eCf4e5e6eMb6fNbObPbQbRbSb

168 self._owner = None 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K CdDd4d7f8fEd:cFdGd;c=cDfHdId5dJdKdL M N O P Q 0 6d7d8d9f!f#f| } ~ abpbqbrbsbtbubvb^e_e`epdqdrdR S T Ibwbmeneoepeqe9dScre$fxbse%fte'fbbueveybzb!d#d$d%d'd{ 7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb{e|ecede,d(fTd-d~cldadUdfdgdhdmda b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIcndodKc3d_ jb}cLc}e~eaf.d/d:d;d=d?d@d[d]d^d_d`d{didee{cfe/cobCbjd]cMc?ckd@c[cOcPcNcQcd e f ,eRcEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZf0f1f2f3fdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAfbdcdbfcf4f5f[e]e)f*fsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud` JbKbLbwexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf+f,f2e3eCf4e5e6eMb6fNbObPbQbRbSb

169 self._mem_attrs_inited.store(False) 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K CdDd4d7f8fEd:cFdGd;c=cDfHdId5dJdKdL M N O P Q 0 6d7d8d9f!f#f| } ~ abpbqbrbsbtbubvb^e_e`epdqdrdR S T Ibwbmeneoepeqe9dScre$fxbse%fte'fbbueveybzb!d#d$d%d'd{ 7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb{e|ecede,d(fTd-d~cldadUdfdgdhdmda b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIcndodKc3d_ jb}cLc}e~eaf.d/d:d;d=d?d@d[d]d^d_d`d{didee{cfe/cobCbjd]cMc?ckd@c[cOcPcNcQcd e f ,eRcEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZf0f1f2f3fdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAfbdcdbfcf4f5f[e]e)f*fsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud` JbKbLbwexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf+f,f2e3eCf4e5e6eMb6fNbObPbQbRbSb

170  

171 def __init__(self, *args, **kwargs) -> None: 

172 raise RuntimeError("Buffer objects cannot be instantiated directly. " 

173 "Please use MemoryResource APIs.") 

174  

175 @classmethod 

176 def _init( 

177 cls, ptr: DevicePointerType, size_t size, mr: MemoryResource | None = None, 

178 ipc_descriptor: IPCBufferDescriptor | None = None, 

179 owner : object | None = None 

180 ) -> Buffer: 

181 """Create a Buffer from a raw pointer. 

182  

183 When ``mr`` is provided, the buffer takes ownership: ``mr.deallocate()`` 

184 is called when the buffer is closed or garbage collected. When ``owner`` 

185 is provided, the owner is kept alive but no deallocation is performed. 

186 """ 

187 if mr is not None and owner is not None: 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 | } ~ abpbqbrbsbtbubvbR S T meneoepeqeScresetebbueve{ TbUbVbDbEbFbcbkbGbHbebfblbmbgbhbcedea b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIc3d_ ~fee{cfe/cjd@c[cOcPcNcQcd e f Rc` JbKbLbMbNbObPbQbRbSb

188 raise ValueError("owner and memory resource cannot be both specified together") 2~f

189 cdef Buffer self = Buffer.__new__(cls) 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 | } ~ abpbqbrbsbtbubvbR S T meneoepeqeScresetebbueve{ TbUbVbDbEbFbcbkbGbHbebfblbmbgbhbcedea b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIc3d_ ee{cfe/cjd@c[cOcPcNcQcd e f Rc` JbKbLbMbNbObPbQbRbSb

190 cdef uintptr_t c_ptr = <uintptr_t>(int(ptr)) 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 | } ~ abpbqbrbsbtbubvbR S T meneoepeqeScresetebbueve{ TbUbVbDbEbFbcbkbGbHbebfblbmbgbhbcedea b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIc3d_ ee{cfe/cjd@c[cOcPcNcQcd e f Rc` JbKbLbMbNbObPbQbRbSb

191 if mr is not None: 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 | } ~ abpbqbrbsbtbubvbR S T meneoepeqeScresetebbueve{ TbUbVbDbEbFbcbkbGbHbebfblbmbgbhbcedea b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIc3d_ ee{cfe/cjd@c[cOcPcNcQcd e f Rc` JbKbLbMbNbObPbQbRbSb

192 self._h_ptr = deviceptr_create_with_mr(c_ptr, size, mr) 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 | } ~ abpbqbrbsbtbubvbR S T meneoepeqeScresetebbueve{ TbUbVbDbEbFbcbkbGbHbebfblbmbgbhbcedea b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bW X VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIc3d_ ee{cfe/c@c[cOcPcNcQcd e f

193 else: 

194 self._h_ptr = deviceptr_create_with_owner(c_ptr, owner) 2meneoepeqeScresetebbueve{ U V dbAbBbW X Y Z jdRc` JbKbLbMbNbObPbQbRbSb

195 self._size = size 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 | } ~ abpbqbrbsbtbubvbR S T meneoepeqeScresetebbueve{ TbUbVbDbEbFbcbkbGbHbebfblbmbgbhbcedea b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIc3d_ ee{cfe/cjd@c[cOcPcNcQcd e f Rc` JbKbLbMbNbObPbQbRbSb

196 self._memory_resource = mr 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 | } ~ abpbqbrbsbtbubvbR S T meneoepeqeScresetebbueve{ TbUbVbDbEbFbcbkbGbHbebfblbmbgbhbcedea b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIc3d_ ee{cfe/cjd@c[cOcPcNcQcd e f Rc` JbKbLbMbNbObPbQbRbSb

197 self._ipc_data = IPCDataForBuffer(ipc_descriptor, True) if ipc_descriptor is not None else None 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 | } ~ abpbqbrbsbtbubvbR S T meneoepeqeScresetebbueve{ TbUbVbDbEbFbcbkbGbHbebfblbmbgbhbcedea b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIc3d_ ee{cfe/cjd@c[cOcPcNcQcd e f Rc` JbKbLbMbNbObPbQbRbSb

198 self._owner = owner 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 | } ~ abpbqbrbsbtbubvbR S T meneoepeqeScresetebbueve{ TbUbVbDbEbFbcbkbGbHbebfblbmbgbhbcedea b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIc3d_ ee{cfe/cjd@c[cOcPcNcQcd e f Rc` JbKbLbMbNbObPbQbRbSb

199 self._mem_attrs_inited.store(False) 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 | } ~ abpbqbrbsbtbubvbR S T meneoepeqeScresetebbueve{ TbUbVbDbEbFbcbkbGbHbebfblbmbgbhbcedea b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIc3d_ ee{cfe/cjd@c[cOcPcNcQcd e f Rc` JbKbLbMbNbObPbQbRbSb

200 return self 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 | } ~ abpbqbrbsbtbubvbR S T meneoepeqeScresetebbueve{ TbUbVbDbEbFbcbkbGbHbebfblbmbgbhbcedea b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIc3d_ ee{cfe/cjd@c[cOcPcNcQcd e f Rc` JbKbLbMbNbObPbQbRbSb

201  

202 @staticmethod 

203 def _reduce_helper(mr, ipc_descriptor): 

204 # The parent process's stream is not portable across processes, so the 

205 # pickle path cannot thread an explicit stream through. Seed the 

206 # imported buffer's deallocation with the current context's default 

207 # stream; the receiver can override via buffer.close(stream). 

208 return Buffer.from_ipc_descriptor(mr, ipc_descriptor, stream=default_stream()) 

209  

210 def __reduce__(self) -> tuple[object, ...]: 

211 # Unpickling performs a live CUDA IPC import from descriptor bytes in the 

212 # pickle stream. Only deserialize Buffers from a trusted principal. 

213 # Must not serialize the parent's stream! 

214 return Buffer._reduce_helper, (self.memory_resource, self.ipc_descriptor) 27e8e9e!e#e$eTbUb%e'e(e)e*e+eLdMdNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfbgbhb

215  

216 @staticmethod 

217 def from_handle( 

218 ptr: DevicePointerType, size_t size, mr: MemoryResource | None = None, 

219 owner: object | None = None, 

220 ) -> Buffer: 

221 """Create a new :class:`Buffer` object from a pointer. 

222  

223 Parameters 

224 ---------- 

225 ptr : :obj:`~_memory.DevicePointerType` 

226 Allocated buffer handle object 

227 size : int 

228 Memory size of the buffer 

229 mr : :obj:`~_memory.MemoryResource`, optional 

230 Memory resource associated with the buffer. When provided, 

231 :meth:`MemoryResource.deallocate` is called when the buffer is 

232 closed or garbage collected. 

233 owner : object, optional 

234 An object holding external allocation that the ``ptr`` points to. 

235 The reference is kept as long as the buffer is alive. 

236 The ``owner`` and ``mr`` cannot be specified together. 

237  

238 Note 

239 ---- 

240 When neither ``mr`` nor ``owner`` is specified, this creates a 

241 non-owning reference. The pointer will NOT be freed when the 

242 :class:`Buffer` is closed or garbage collected. 

243 """ 

244 return Buffer._init(ptr, size, mr=mr, owner=owner) 2| } ~ abpbqbrbsbtbubvbmeneoepeqeScresetebbueve{ TbUbVbDbEbFbcbkbGbHbebfblbmbgbhb^c_c`cUcJcvcTcdd|cedibnb:bU V dbAbBbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIc_ ~fee{cfe/cjdOcPcNcQcRc` JbKbLbMbNbObPbQbRbSb

245  

246 @classmethod 

247 def from_ipc_descriptor( 

248 cls, mr: DeviceMemoryResource | PinnedMemoryResource, ipc_descriptor: IPCBufferDescriptor, 

249 *, stream: Stream 

250 ) -> Buffer: 

251 """Import a buffer that was exported from another process. 

252  

253 Parameters 

254 ---------- 

255 mr : :obj:`~_memory.DeviceMemoryResource` | :obj:`~_memory.PinnedMemoryResource` 

256 The IPC-enabled memory resource matching the exporting process. 

257 ipc_descriptor : :obj:`~_memory.IPCBufferDescriptor` 

258 The descriptor exported from another process. 

259 stream : :obj:`~_stream.Stream` 

260 Keyword-only. The stream used for asynchronous deallocation when 

261 the buffer is closed or garbage collected. 

262  

263 Note 

264 ---- 

265 The descriptor payload and ``size`` are supplied by the exporting peer 

266 and must be treated as untrusted input unless the peer is known to be 

267 cooperating. 

268 """ 

269 return _ipc.Buffer_from_ipc_descriptor(cls, mr, ipc_descriptor, stream) 2agbgidkd

270  

271 @property 

272 @cython.critical_section 

273 def ipc_descriptor(self) -> IPCBufferDescriptor: 

274 """Descriptor for sharing this buffer with other processes.""" 

275 if self._ipc_data is None: 27e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhbid?ckdbdcd

276 self._ipc_data = IPCDataForBuffer(_ipc.Buffer_get_ipc_descriptor(self), False) 27e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhbid?ckdbdcd

277 return self._ipc_data.ipc_descriptor 27e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb?cbdcd

278  

279 def close(self, stream: Stream | GraphBuilder | None = None) -> None: 

280 """Deallocate this buffer asynchronously on the given stream. 

281  

282 This buffer is released back to their memory resource 

283 asynchronously on the given stream. 

284  

285 Parameters 

286 ---------- 

287 stream : :obj:`~_stream.Stream` | :obj:`~graph.GraphBuilder`, optional 

288 The stream object to use for asynchronous deallocation. If None, 

289 the deallocation stream stored in the handle is used. 

290 """ 

291 Buffer_close(self, stream) 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K 4d:cGd;c=cHdId5dJdKdL M N O P Q 6d7d8d| } ~ abpbqbrbsbtbubvbpdqdrdR S T Ibwb-f.f/f:f;f9dSc=f^fxb?f_f@f`fbb[f]fybzb!d#d$d%d'd{ cbkbebfblbmbgbhb,dTd-d~cldadUdfdgdhdmdUcJcvcU V dbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIcndodKc}cLc.d/d:d;d=d?d@d[d]d^d_d`d{did{c/cobCbjd]cMc?ckd@c[cOcPcNcQcbdcdsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud

292  

293 def __enter__(self): 

294 return self 2~cldadgdhdmd

295  

296 def __exit__(self, exc_type, exc_val, exc_tb): 

297 self.close() 2~cldadgdhdmd

298 return False 2~cldadgdhdmd

299  

300 def copy_to(self, dst: Buffer | None = None, *, stream: Stream | GraphBuilder) -> Buffer: 

301 """Copy from this buffer to the dst buffer asynchronously on the given stream. 

302  

303 Copies the data from this buffer to the provided dst buffer. 

304 If the dst buffer is not provided, then a new buffer is first 

305 allocated using the associated memory resource before the copy. 

306  

307 Parameters 

308 ---------- 

309 dst : :obj:`~_memory.Buffer`, optional 

310 Destination buffer to copy data to. If not provided, a new buffer 

311 is allocated using this buffer's memory resource. 

312 stream : :obj:`~_stream.Stream` | :obj:`~graph.GraphBuilder` 

313 Keyword argument specifying the stream for the 

314 asynchronous copy 

315  

316 """ 

317 cdef Stream s = Stream_accept(stream) 2a b c vcKcLcMcd e f

318 cdef size_t src_size = self._size 2a b c vcKcLcMcd e f

319  

320 if dst is None: 2a b c vcKcLcMcd e f

321 if self._memory_resource is None: 

322 raise ValueError("a destination buffer must be provided (this " 

323 "buffer does not have a memory_resource)") 

324 dst = self._memory_resource.allocate(src_size, stream=s) 

325  

326 cdef size_t dst_size = dst._size 2a b c vcKcLcMcd e f

327 if dst_size != src_size: 2a b c vcKcLcMcd e f

328 raise ValueError( "buffer sizes mismatch between src and dst (sizes " 

329 f"are: src={src_size}, dst={dst_size})" 

330 ) 

331 with nogil: 2a b c vcKcLcMcd e f

332 HANDLE_RETURN(cydriver.cuMemcpyAsync( 2a b c vcKcLcMcd e f

333 as_cu(dst._h_ptr), as_cu(self._h_ptr), src_size, as_cu(s._h_stream))) 

334 return dst 2a b c vcKcLcMcd e f

335  

336 def copy_from(self, src: Buffer, *, stream: Stream | GraphBuilder) -> None: 

337 """Copy from the src buffer to this buffer asynchronously on the given stream. 

338  

339 Parameters 

340 ---------- 

341 src : :obj:`~_memory.Buffer` 

342 Source buffer to copy data from 

343 stream : :obj:`~_stream.Stream` | :obj:`~graph.GraphBuilder` 

344 Keyword argument specifying the stream for the 

345 asynchronous copy 

346  

347 """ 

348 cdef Stream s = Stream_accept(stream) 2| } ~ abpbqbrbsbtbubvbTbUbVbDbEbFbcbkbGbHbebfblbmbgbhb^c_c`cJc

349 cdef size_t dst_size = self._size 2| } ~ abpbqbrbsbtbubvbTbUbVbDbEbFbcbkbGbHbebfblbmbgbhb^c_c`cJc

350 cdef size_t src_size = src._size 2| } ~ abpbqbrbsbtbubvbTbUbVbDbEbFbcbkbGbHbebfblbmbgbhb^c_c`cJc

351  

352 if src_size != dst_size: 2| } ~ abpbqbrbsbtbubvbTbUbVbDbEbFbcbkbGbHbebfblbmbgbhb^c_c`cJc

353 raise ValueError( "buffer sizes mismatch between src and dst (sizes " 

354 f"are: src={src_size}, dst={dst_size})" 

355 ) 

356 with nogil: 2| } ~ abpbqbrbsbtbubvbTbUbVbDbEbFbcbkbGbHbebfblbmbgbhb^c_c`cJc

357 HANDLE_RETURN(cydriver.cuMemcpyAsync( 2| } ~ abpbqbrbsbtbubvbTbUbVbDbEbFbcbkbGbHbebfblbmbgbhb^c_c`cJc

358 as_cu(self._h_ptr), as_cu(src._h_ptr), dst_size, as_cu(s._h_stream))) 

359  

360 def fill(self, value: int | BufferProtocol, *, stream: Stream | GraphBuilder) -> None: 

361 """Fill this buffer with a repeating byte pattern. 

362  

363 Parameters 

364 ---------- 

365 value : int | :obj:`collections.abc.Buffer` 

366 - int: Must be in range [0, 256). Converted to 1 byte. 

367 - :obj:`collections.abc.Buffer`: Must be 1, 2, or 4 bytes. 

368 stream : :obj:`~_stream.Stream` | :obj:`~graph.GraphBuilder` 

369 Stream for the asynchronous fill operation. 

370  

371 Raises 

372 ------ 

373 TypeError 

374 If value is not an int and does not support the buffer protocol. 

375 ValueError 

376 If value byte length is not 1, 2, or 4. 

377 If buffer size is not divisible by value byte length. 

378 OverflowError 

379 If int value is outside [0, 256). 

380  

381 """ 

382 cdef Stream s_stream = Stream_accept(stream) 2CdDdEd:cFd;c=c| } ~ abVcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.c

383 cdef unsigned int val 

384 cdef unsigned int elem_size 

385 val, elem_size = _parse_fill_value(value) 2CdDdEd:cFd;c=c| } ~ abVcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.c

386  

387 cdef size_t buffer_size = self._size 2CdDdEd:cFd;c=c| } ~ abocwc;bxc=bpc?bqcrcsc@b[b]b^b_b`btcuc{b|byc}b~bzcacAcWbBcXbbcYbccdcecZb0b1b2b3b4bfcgc5b6bCc7b8bDchcEc9bFc!bic#bjckclc$b%b'b(b)b*bmcnc+b,bGc-b.bHc

388 cdef cydriver.CUdeviceptr dst = as_cu(self._h_ptr) 2CdDdEd:cFd;c=c| } ~ abocwc;bxc=bpc?bqcrcsc@b[b]b^b_b`btcuc{b|byc}b~bzcacAcWbBcXbbcYbccdcecZb0b1b2b3b4bfcgc5b6bCc7b8bDchcEc9bFc!bic#bjckclc$b%b'b(b)b*bmcnc+b,bGc-b.bHc

389 cdef cydriver.CUstream s = as_cu(s_stream._h_stream) 2CdDdEd:cFd;c=c| } ~ abocwc;bxc=bpc?bqcrcsc@b[b]b^b_b`btcuc{b|byc}b~bzcacAcWbBcXbbcYbccdcecZb0b1b2b3b4bfcgc5b6bCc7b8bDchcEc9bFc!bic#bjckclc$b%b'b(b)b*bmcnc+b,bGc-b.bHc

390  

391 if elem_size == 1: 2CdDdEd:cFd;c=c| } ~ abocwc;bxc=bpc?bqcrcsc@b[b]b^b_b`btcuc{b|byc}b~bzcacAcWbBcXbbcYbccdcecZb0b1b2b3b4bfcgc5b6bCc7b8bDchcEc9bFc!bic#bjckclc$b%b'b(b)b*bmcnc+b,bGc-b.bHc

392 with nogil: 2CdDdEd:cFd;c=c| } ~ abocpcqcrcsctcucacbcccdcecfcgchcicjckclcmcnc

393 HANDLE_RETURN(cydriver.cuMemsetD8Async(dst, val, buffer_size, s)) 2CdDdEd:cFd;c=c| } ~ abocpcqcrcsctcucacbcccdcecfcgchcicjckclcmcnc

394 elif elem_size == 2: 

395 if buffer_size & 0x1: 2wc;b@b[b]b{b|bycAcWbZb0b1b5b6bCcEc9b$b%b'b+b,bGc

396 raise ValueError(f"buffer size ({buffer_size}) must be divisible by 2") 2wcycAcCcEcGc

397 with nogil: 2;b@b[b]b{b|bWbZb0b1b5b6b9b$b%b'b+b,b

398 HANDLE_RETURN(cydriver.cuMemsetD16Async(dst, val, buffer_size // 2, s)) 2;b@b[b]b{b|bWbZb0b1b5b6b9b$b%b'b+b,b

399 elif elem_size == 4: 

400 if buffer_size & 0x3: 2xc=b?b^b_b`b}b~bzcBcXbYb2b3b4b7b8bDcFc!b#b(b)b*b-b.bHc

401 raise ValueError(f"buffer size ({buffer_size}) must be divisible by 4") 2xczcBcDcFcHc

402 with nogil: 2=b?b^b_b`b}b~bXbYb2b3b4b7b8b!b#b(b)b*b-b.b

403 HANDLE_RETURN(cydriver.cuMemsetD32Async(dst, val, buffer_size // 4, s)) 2=b?b^b_b`b}b~bXbYb2b3b4b7b8b!b#b(b)b*b-b.b

404  

405 def __dlpack__( 

406 self, 

407 *, 

408 stream: int | None = None, 

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

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

411 copy: bool | None = None, 

412 ) -> object: 

413 # Note: we ignore the stream argument entirely (as if it is -1). 

414 # It is the user's responsibility to maintain stream order. 

415 if dl_device is not None: 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ Tc:b_ jbd e f

416 raise BufferError("Sorry, not supported: dl_device other than None") 2:b

417 if copy is True: 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ Tc:b_ jbd e f

418 raise BufferError("Sorry, not supported: copy=True") 2:b

419 if max_version is None: 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ Tc:b_ jbd e f

420 versioned = False 2Tc:b

421 else: 

422 if not isinstance(max_version, tuple) or len(max_version) != 2: 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ :b_ jbd e f

423 raise BufferError(f"Expected max_version tuple[int, int], got {max_version}") 2:b

424 versioned = max_version >= (1, 0) 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ :b_ jbd e f

425 capsule = make_py_capsule(self, versioned) 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ Tc:b_ jbd e f

426 return capsule 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ :b_ jbd e f

427  

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

429 return classify_dl_device(self) 2dd|cedibnb_ jb

430  

431 def __buffer__(self, flags: int, /) -> memoryview: 

432 # Support for Python-level buffer protocol as per PEP 688. 

433 # This raises a BufferError unless: 

434 # 1. Python is 3.12+ 

435 # 2. This Buffer object is host accessible 

436 raise NotImplementedError("WIP: Buffer.__buffer__ hasn't been implemented yet.") 

437  

438 def __release_buffer__(self, buffer: memoryview, /) -> None: 

439 # Supporting method paired with __buffer__. 

440 raise NotImplementedError("WIP: Buffer.__release_buffer__ hasn't been implemented yet.") 

441  

442 @property 

443 def device_id(self) -> int: 

444 """Return the device ordinal of this buffer.""" 

445 if self._memory_resource is not None: 2^e_e`e{e|e|c:bU V dbAbBbW X Y Z ndod}e~eaf]cOcPcQc` JbKbLbwexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eMbNbObPbQbRbSb

446 return self._memory_resource.device_id 2^e_e`e{e|e|c:bndod}e~eaf]cOcPcQcwexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e

447 _init_memory_attrs(self) 2U V dbAbBbW X Y Z ` JbKbLbMbNbObPbQbRbSb

448 return self._mem_attrs.device_id 2U V dbAbBbW X Y Z ` JbKbLbMbNbObPbQbRbSb

449  

450 @property 

451 def handle(self) -> int: 

452 """Return the buffer handle object. 

453  

454 .. caution:: 

455  

456 This handle is a Python object. To get the memory address of the underlying C 

457 handle, call ``int(Buffer.handle)``. 

458 """ 

459 # Return raw integer for compatibility with ctypes and other tools 

460 # that expect a raw pointer value 

461 return as_intptr(self._h_ptr) 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K CdDdEd:cFdGd;c=cDfHdIdJdKdL M N O P Q 0 | } ~ abpbqbrbsbtbubvb^e_e`eR S T wbvdmewdnexdoeydpeqeScrexbzdseAdtebbueBdveybzb{ TbUbVbDbEbFbcbkbGbHbebfblbmbgbhb{e|ecedeTd~cadfdhda b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ UcJcvcTc:bU V W X acWbXbbcYbccdcecZb0b1b2b3b4bfcgc5b6b7b8bhc9b!bic#bjckclc$b%b'b(b)b*bmcnc+b,b-b.bIcKc3d_ jbLc}e~eafMc@cNcQcd e f ,eRcsdtdud` JbKbLbwexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eMb6fNbObPbQbRbSb

462  

463 def __eq__(self, other: object) -> bool: 

464 if not isinstance(other, Buffer): 2,eRcdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAfcf[e]e

465 return NotImplemented 2,edfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAf

466 cdef Buffer other_buf = <Buffer>other 2,eRccf[e]e

467 return (as_intptr(self._h_ptr) == as_intptr(other_buf._h_ptr) and 2,eRccf[e]e

468 self._size == other_buf._size) 2,eRc[e]e

469  

470 def __hash__(self) -> int: 

471 return hash((as_intptr(self._h_ptr), self._size)) 2RcEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZf0f1f2f3f4f5f[e]e

472  

473 def __repr__(self) -> str: 

474 maybe_is_mapped = " is_mapped=True" if self.is_mapped else "" 2TbUb(d)dLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdbf

475 return f"<Buffer ptr={as_intptr(self._h_ptr):#x} size={self._size}{maybe_is_mapped}>" 2TbUb(d)dLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdbf

476  

477 @property 

478 def is_device_accessible(self) -> bool: 

479 """Return True if this buffer can be accessed by the GPU, otherwise False.""" 

480 if self._memory_resource is not None: 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ Tcdd|cedibnb:bU V dbAbBbW X Y Z Ic_ jb}c]c?cd e f ` JbKbLbwexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eMbNbObPbQbRbSb

481 return self._memory_resource.is_device_accessible 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ Tcdd|cedibnb:bIc_ jb}c]c?cd e f wexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e

482 _init_memory_attrs(self) 2U V dbAbBbW X Y Z ` JbKbLbMbNbObPbQbRbSb

483 return self._mem_attrs.is_device_accessible 2U V dbAbBbW X Y Z ` JbKbLbMbNbObPbQbRbSb

484  

485 @property 

486 def is_host_accessible(self) -> bool: 

487 """Return True if this buffer can be accessed by the CPU, otherwise False.""" 

488 if self._memory_resource is not None: 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ Tcdd|cedibnb:bU V dbAbBbW X Y Z oc;b=bpc?bqcrcsc@b[b]b^b_b`btcuc{b|b}b~bacWbXbbcYbccdcecZb0b1b2b3b4bfcgc5b6b7b8bhc9b!bic#bjckclc$b%b'b(b)b*bmcnc+b,b-b.bIc_ jb}c]c?cd e f `

489 return self._memory_resource.is_host_accessible 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ Tcdd|cedibnb:boc;b=bpc?bqcrcsc@b[b]b^b_b`btcuc{b|b}b~bacWbXbbcYbccdcecZb0b1b2b3b4bfcgc5b6b7b8bhc9b!bic#bjckclc$b%b'b(b)b*bmcnc+b,b-b.bIc_ jb}c]c?cd e f

490 _init_memory_attrs(self) 2U V dbAbBbW X Y Z `

491 return self._mem_attrs.is_host_accessible 2U V dbAbBbW X Y Z `

492  

493 @property 

494 def is_managed(self) -> bool: 

495 """Return True if this buffer is CUDA managed (unified) memory, otherwise False.""" 

496 _init_memory_attrs(self) 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnb_ jbobCbd e f

497 if self._mem_attrs.is_managed: 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzb{ a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibnb_ jbobCbd e f

498 return True 2IbwbvdwdxdydgeheiexbzdAdjekebbleBdybzbnb_ jb

499 # Pool-allocated managed memory does not set CU_POINTER_ATTRIBUTE_IS_MANAGED, 

500 # so fall back to the memory resource when it advertises managed allocations. 

501 return self._memory_resource is not None and self._memory_resource.is_managed 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T { a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibobCbd e f

502  

503 @property 

504 def is_mapped(self) -> bool: 

505 """Return True if this buffer is mapped into the process via IPC.""" 

506 return getattr(self._ipc_data, "is_mapped", False) 2TbUb(d)dLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdIcbf

507  

508  

509 @property 

510 def memory_resource(self) -> MemoryResource: 

511 """Return the memory resource associated with this buffer.""" 

512 return self._memory_resource 2| } ~ abpbqbrbsbtbubvb7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhbUcIcKc}cLcid]cMc?ckdOcPcbdcdJbKbLbwexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf2e3eCf4e5e6eMbNbObPbQbRbSb

513  

514 @property 

515 def size(self) -> int: 

516 """Return the memory size of this buffer.""" 

517 return self._size 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 | } ~ abpbqbrbsbtbubvb^e_e`eR S T wbvdmewdnexdoeydpeqeScrexbzdseAdtebbueBdveybzb{ 7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb{e|e~cadUdfdgda b c ^c_c`c1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ Tc:bIcndodKc3d_ jb}cLc}e~eaf]cMc?c@cOcPcNcQcd e f RcbdcdsdVdWdXdYdZd0d1d2dtdudwexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf2e3eCf4e5e6e

518  

519 @property 

520 def owner(self) -> object: 

521 """Return the object holding external allocation.""" 

522 return self._owner 

523  

524  

525cdef class MemoryResource: 

526 """Abstract base class for memory resources that manage allocation and 

527 deallocation of buffers. 

528  

529 Subclasses must implement methods for allocating and deallocation, as well 

530 as properties associated with this memory resource from which all allocated 

531 buffers will inherit. (Since all :class:`Buffer` instances allocated and 

532 returned by the :meth:`allocate` method would hold a reference to self, the 

533 buffer properties are retrieved simply by looking up the underlying memory 

534 resource's respective property.) 

535 """ 

536  

537 def allocate(self, size_t size, *, stream: Stream | GraphBuilder) -> Buffer: 

538 """Allocate a buffer of the requested size. 

539  

540 Parameters 

541 ---------- 

542 size : int 

543 The size of the buffer to allocate, in bytes. 

544 stream : :obj:`~_stream.Stream` | :obj:`~graph.GraphBuilder` 

545 Keyword-only. The stream on which to perform the allocation 

546 asynchronously. Must be passed explicitly; pass 

547 ``device.default_stream`` to use the default stream. 

548  

549 Returns 

550 ------- 

551 Buffer 

552 The allocated buffer object, which can be used for device or host operations 

553 depending on the resource's properties. 

554 """ 

555 raise TypeError("MemoryResource.allocate must be implemented by subclasses.") 

556  

557 def deallocate( 

558 self, 

559 ptr: DevicePointerType, 

560 size_t size, 

561 *, 

562 stream: Stream | GraphBuilder 

563 ) -> None: 

564 """Deallocate a buffer previously allocated by this resource. 

565  

566 Parameters 

567 ---------- 

568 ptr : :obj:`~_memory.DevicePointerType` 

569 The pointer or handle to the buffer to deallocate. 

570 size : int 

571 The size of the buffer to deallocate, in bytes. 

572 stream : :obj:`~_stream.Stream` | :obj:`~graph.GraphBuilder` 

573 Keyword-only. The stream on which to perform the deallocation 

574 asynchronously. Must be passed explicitly; pass 

575 ``device.default_stream`` to use the default stream. 

576 """ 

577 raise TypeError("MemoryResource.deallocate must be implemented by subclasses.") 

578  

579 @property 

580 def is_device_accessible(self) -> bool: 

581 """Whether buffers allocated by this resource are device-accessible.""" 

582 raise TypeError("MemoryResource.is_device_accessible must be implemented by subclasses.") 

583  

584 @property 

585 def is_host_accessible(self) -> bool: 

586 """Whether buffers allocated by this resource are host-accessible.""" 

587 raise TypeError("MemoryResource.is_host_accessible must be implemented by subclasses.") 

588  

589 @property 

590 def is_managed(self) -> bool: 

591 """Whether buffers allocated by this resource are CUDA managed (unified) memory.""" 

592 return False 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q 0 R S T a b c 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ; = ? @ [ ] ^ ibobCbd e f

593  

594 @property 

595 def device_id(self) -> int: 

596 """Device ID associated with this memory resource, or -1 if not applicable.""" 

597 raise TypeError("MemoryResource.device_id must be implemented by subclasses.") 

598  

599  

600# Buffer Implementation Helpers 

601# ----------------------------- 

602cdef Buffer Buffer_from_deviceptr_handle( 

603 DevicePtrHandle h_ptr, 

604 size_t size, 

605 MemoryResource mr, 

606 object ipc_descriptor = None, 

607 type cls = Buffer, 

608): 

609 """Create a Buffer (or subclass instance) from an existing DevicePtrHandle.""" 

610 cdef Buffer buf = cls.__new__(cls) 2CdDd4d7f8fEd:cFdGd;c=cDfHdId5dJdKd6d7d8d9f!f#f| } ~ abpbqbrbsbtbubvb^e_e`epdqdrdIbwb9d$fxb%f'fybzb!d#d$d%d'd7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb{e|e,d(fTd-d~cldadUdfdgdhdmda b c U V ndodKcjb}cLc}e~eaf.d/d:d;d=d?d@d[d]d^d_d`d{didobCb]cMc?ckdd e f ,eRcEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZf0f1f2f3fdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAfbdcdbfcf4f5f[e]e)f*fsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud` wexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf+f,f2e3eCf4e5e6e6f

611 buf._h_ptr = h_ptr 2CdDd4d7f8fEd:cFdGd;c=cDfHdId5dJdKd6d7d8d9f!f#f| } ~ abpbqbrbsbtbubvb^e_e`epdqdrdIbwb9d$fxb%f'fybzb!d#d$d%d'd7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb{e|e,d(fTd-d~cldadUdfdgdhdmda b c U V ndodKcjb}cLc}e~eaf.d/d:d;d=d?d@d[d]d^d_d`d{didobCb]cMc?ckdd e f ,eRcEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZf0f1f2f3fdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAfbdcdbfcf4f5f[e]e)f*fsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud` wexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf+f,f2e3eCf4e5e6e6f

612 buf._size = size 2CdDd4d7f8fEd:cFdGd;c=cDfHdId5dJdKd6d7d8d9f!f#f| } ~ abpbqbrbsbtbubvb^e_e`epdqdrdIbwb9d$fxb%f'fybzb!d#d$d%d'd7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb{e|e,d(fTd-d~cldadUdfdgdhdmda b c U V ndodKcjb}cLc}e~eaf.d/d:d;d=d?d@d[d]d^d_d`d{didobCb]cMc?ckdd e f ,eRcEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZf0f1f2f3fdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAfbdcdbfcf4f5f[e]e)f*fsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud` wexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf+f,f2e3eCf4e5e6e6f

613 buf._memory_resource = mr 2CdDd4d7f8fEd:cFdGd;c=cDfHdId5dJdKd6d7d8d9f!f#f| } ~ abpbqbrbsbtbubvb^e_e`epdqdrdIbwb9d$fxb%f'fybzb!d#d$d%d'd7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb{e|e,d(fTd-d~cldadUdfdgdhdmda b c U V ndodKcjb}cLc}e~eaf.d/d:d;d=d?d@d[d]d^d_d`d{didobCb]cMc?ckdd e f ,eRcEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZf0f1f2f3fdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAfbdcdbfcf4f5f[e]e)f*fsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud` wexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf+f,f2e3eCf4e5e6e6f

614 buf._ipc_data = IPCDataForBuffer(ipc_descriptor, True) if ipc_descriptor is not None else None 2CdDd4d7f8fEd:cFdGd;c=cDfHdId5dJdKd6d7d8d9f!f#f| } ~ abpbqbrbsbtbubvb^e_e`epdqdrdIbwb9d$fxb%f'fybzb!d#d$d%d'd7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb{e|e,d(fTd-d~cldadUdfdgdhdmda b c U V ndodKcjb}cLc}e~eaf.d/d:d;d=d?d@d[d]d^d_d`d{didobCb]cMc?ckdd e f ,eRcEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZf0f1f2f3fdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAfbdcdbfcf4f5f[e]e)f*fsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud` wexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf+f,f2e3eCf4e5e6e6f

615 buf._owner = None 2CdDd4d7f8fEd:cFdGd;c=cDfHdId5dJdKd6d7d8d9f!f#f| } ~ abpbqbrbsbtbubvb^e_e`epdqdrdIbwb9d$fxb%f'fybzb!d#d$d%d'd7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb{e|e,d(fTd-d~cldadUdfdgdhdmda b c U V ndodKcjb}cLc}e~eaf.d/d:d;d=d?d@d[d]d^d_d`d{didobCb]cMc?ckdd e f ,eRcEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZf0f1f2f3fdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAfbdcdbfcf4f5f[e]e)f*fsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud` wexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf+f,f2e3eCf4e5e6e6f

616 buf._mem_attrs_inited.store(False) 2CdDd4d7f8fEd:cFdGd;c=cDfHdId5dJdKd6d7d8d9f!f#f| } ~ abpbqbrbsbtbubvb^e_e`epdqdrdIbwb9d$fxb%f'fybzb!d#d$d%d'd7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb{e|e,d(fTd-d~cldadUdfdgdhdmda b c U V ndodKcjb}cLc}e~eaf.d/d:d;d=d?d@d[d]d^d_d`d{didobCb]cMc?ckdd e f ,eRcEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZf0f1f2f3fdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAfbdcdbfcf4f5f[e]e)f*fsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud` wexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf+f,f2e3eCf4e5e6e6f

617 return buf 2CdDd4d7f8fEd:cFdGd;c=cDfHdId5dJdKd6d7d8d9f!f#f| } ~ abpbqbrbsbtbubvb^e_e`epdqdrdIbwb9d$fxb%f'fybzb!d#d$d%d'd7e8e9e!e#e$e-e.eTbUb(d)d%e/e'e:e(e;e)e=e*e?e+e@eLdMd*d+dNdOdVbDbEbFbcbkbGbHbPdQdRdSdebfblbmbgbhb{e|e,d(fTd-d~cldadUdfdgdhdmda b c U V ndodKcjb}cLc}e~eaf.d/d:d;d=d?d@d[d]d^d_d`d{didobCb]cMc?ckdd e f ,eRcEfFfGfHfIfJfKfLfMfNfOfPfQfRfSfTfUfVfWfXfYfZf0f1f2f3fdfefffgfhfifjfkflfmfnfofpfqfrfsftfufvfwfxfyfzfAfbdcdbfcf4f5f[e]e)f*fsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud` wexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1eBf+f,f2e3eCf4e5e6e6f

618  

619  

620cdef inline void Buffer_close(Buffer self, object stream): 

621 """Close a buffer, freeing its memory.""" 

622 cdef Stream s 

623 if not self._h_ptr: 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K 4d:cGd;c=cHdId5dJdKdL M N O P Q 6d7d8d| } ~ abpbqbrbsbtbubvbpdqdrdR S T Ibwb-f.f/f:f;f9dSc=f^fxb?f_f@f`fbb[f]fybzb!d#d$d%d'd{ cbkbebfblbmbgbhb,dTd-d~cldadUdfdgdhdmdUcJcvcU V dbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIcndodKc}cLc.d/d:d;d=d?d@d[d]d^d_d`d{did{c/cobCbjd]cMc?ckd@c[cOcPcNcQcbdcdsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud

624 return 

625 # Update deallocation stream if provided 

626 if stream is not None: 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K 4d:cGd;c=cHdId5dJdKdL M N O P Q 6d7d8d| } ~ abpbqbrbsbtbubvbpdqdrdR S T Ibwb-f.f/f:f;f9dSc=f^fxb?f_f@f`fbb[f]fybzb!d#d$d%d'd{ cbkbebfblbmbgbhb,dTd-d~cldadUdfdgdhdmdUcJcvcU V dbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIcndodKc}cLc.d/d:d;d=d?d@d[d]d^d_d`d{did{c/cobCbjd]cMc?ckd@c[cOcPcNcQcbdcdsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud

627 s = Stream_accept(stream) 2pdqdrdfdKcLc/cMc[c

628 set_deallocation_stream(self._h_ptr, s._h_stream) 2pdqdrdfdKcLc/cMc[c

629 # Reset handle - RAII deleter will free the memory (and release owner ref in C++) 

630 self._h_ptr.reset() 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K 4d:cGd;c=cHdId5dJdKdL M N O P Q 6d7d8d| } ~ abpbqbrbsbtbubvbpdqdrdR S T Ibwb-f.f/f:f;f9dSc=f^fxb?f_f@f`fbb[f]fybzb!d#d$d%d'd{ cbkbebfblbmbgbhb,dTd-d~cldadUdfdgdhdmdUcJcvcU V dbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIcndodKc}cLc.d/d:d;d=d?d@d[d]d^d_d`d{did{c/cobCbjd]cMc?ckd@c[cOcPcNcQcbdcdsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud

631 self._size = 0 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K 4d:cGd;c=cHdId5dJdKdL M N O P Q 6d7d8d| } ~ abpbqbrbsbtbubvbpdqdrdR S T Ibwb-f.f/f:f;f9dSc=f^fxb?f_f@f`fbb[f]fybzb!d#d$d%d'd{ cbkbebfblbmbgbhb,dTd-d~cldadUdfdgdhdmdUcJcvcU V dbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIcndodKc}cLc.d/d:d;d=d?d@d[d]d^d_d`d{did{c/cobCbjd]cMc?ckd@c[cOcPcNcQcbdcdsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud

632 self._memory_resource = None 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K 4d:cGd;c=cHdId5dJdKdL M N O P Q 6d7d8d| } ~ abpbqbrbsbtbubvbpdqdrdR S T Ibwb-f.f/f:f;f9dSc=f^fxb?f_f@f`fbb[f]fybzb!d#d$d%d'd{ cbkbebfblbmbgbhb,dTd-d~cldadUdfdgdhdmdUcJcvcU V dbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIcndodKc}cLc.d/d:d;d=d?d@d[d]d^d_d`d{did{c/cobCbjd]cMc?ckd@c[cOcPcNcQcbdcdsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud

633 self._ipc_data = None 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K 4d:cGd;c=cHdId5dJdKdL M N O P Q 6d7d8d| } ~ abpbqbrbsbtbubvbpdqdrdR S T Ibwb-f.f/f:f;f9dSc=f^fxb?f_f@f`fbb[f]fybzb!d#d$d%d'd{ cbkbebfblbmbgbhb,dTd-d~cldadUdfdgdhdmdUcJcvcU V dbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIcndodKc}cLc.d/d:d;d=d?d@d[d]d^d_d`d{did{c/cobCbjd]cMc?ckd@c[cOcPcNcQcbdcdsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud

634 self._owner = None 2g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K 4d:cGd;c=cHdId5dJdKdL M N O P Q 6d7d8d| } ~ abpbqbrbsbtbubvbpdqdrdR S T Ibwb-f.f/f:f;f9dSc=f^fxb?f_f@f`fbb[f]fybzb!d#d$d%d'd{ cbkbebfblbmbgbhb,dTd-d~cldadUdfdgdhdmdUcJcvcU V dbW X Y Z VcWcocwc;bXcxc=bpcYcZc0c?b1cqcrcsc@b[b]b^b_b`b2ctcuc{b|byc}b~bzc3c4c5cacAcWb6cBcXbbc7c8c9cYb!cccdcecZb0b1b2b3b4b#cfcgc5b6bCc7b8bDc$c%c'chcEc9b(cFc!bic)c*c+c#b,cjckclc$b%b'b(b)b*b-cmcnc+b,bGc-b.bHc.cIcndodKc}cLc.d/d:d;d=d?d@d[d]d^d_d`d{did{c/cobCbjd]cMc?ckd@c[cOcPcNcQcbdcdsdVdWd|dXdYdZd0d}d~dae1dbe2dtdud