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

224 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-03-25 01:07 +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 

9  

10from cuda.bindings cimport cydriver 

11from cuda.core._memory._device_memory_resource import DeviceMemoryResource 

12from cuda.core._memory._pinned_memory_resource import PinnedMemoryResource 

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

14from cuda.core._memory cimport _ipc 

15from cuda.core._resource_handles cimport ( 

16 DevicePtrHandle, 

17 StreamHandle, 

18 deviceptr_create_with_owner, 

19 deviceptr_create_with_mr, 

20 register_mr_dealloc_callback, 

21 as_intptr, 

22 as_cu, 

23 set_deallocation_stream, 

24) 

25  

26from cuda.core._stream cimport Stream, Stream_accept 

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

28  

29import sys 

30from typing import TypeVar 

31  

32if sys.version_info >= (3, 12): 

33 from collections.abc import Buffer as BufferProtocol 

34else: 

35 BufferProtocol = object 

36  

37from cuda.core._dlpack import DLDeviceType, make_py_capsule 

38from cuda.core._utils.cuda_utils import driver 

39from cuda.core._device import Device 

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 try: 2H I J g h i j u v w x y z A K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 Yel m p q n o .cZePcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNcibc d lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSbSc/cfcbccc6bdcr

54 stream = None 2H I J g h i j u v w x y z A K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 Yel m p q n o .cZePcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNcibc d lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSbSc/cfcbccc6bdcr

55 if h_stream: 2H I J g h i j u v w x y z A K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 Yel m p q n o .cZePcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNcibc d lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSbSc/cfcbccc6bdcr

56 stream = Stream._from_handle(Stream, h_stream) 2fc

57 mr.deallocate(int(ptr), size, stream) 2H I J g h i j u v w x y z A K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 Yel m p q n o .cZePcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNcibc d lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSbSc/cfcbccc6bdcr

58 except Exception as exc: 26b

59 print(f"Warning: mr.deallocate() failed during Buffer destruction: {exc}", 26b

60 file=sys.stderr) 26b

61  

62register_mr_dealloc_callback(_mr_dealloc_callback) 

63  

64  

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

66  

67  

68DevicePointerT = driver.CUdeviceptr | int | None 

69""" 

70A type union of :obj:`~driver.CUdeviceptr`, `int` and `None` for hinting 

71:attr:`Buffer.handle`. 

72""" 

73  

74cdef class Buffer: 

75 """Represent a handle to allocated memory. 

76  

77 This generic object provides a unified representation for how 

78 different memory resources are to give access to their memory 

79 allocations. 

80  

81 Support for data interchange mechanisms are provided by DLPack. 

82 """ 

83 def __cinit__(self): 

84 self._clear() 2H I J :c;c=cQeReSeg h i j u v w x y z A (d)d*d8c9c!cK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 SdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o +d,d.c^cTe,c_cVc4cWc-cXcYcZc0c5cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb6c7c7bUc8b-d.d/d`c{c|c}c~cadbdcdddedfdgdhd1cSc/cfc2cTc9bOc3cbccc6bdcr 2dgcoepeqereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNe=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele#d$d:d;dOePe%d'dUeVeidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeWeXeOdPdneQdRdB C D E F G

85  

86 def _clear(self): 

87 self._h_ptr.reset() # Release the handle 2H I J :c;c=cQeReSeg h i j u v w x y z A (d)d*d8c9c!cK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 SdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o +d,d.c^cTe,c_cVc4cWc-cXcYcZc0c5cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb6c7c7bUc8b-d.d/d`c{c|c}c~cadbdcdddedfdgdhd1cSc/cfc2cTc9bOc3cbccc6bdcr 2dgcoepeqereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNe=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele#d$d:d;dOePe%d'dUeVeidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeWeXeOdPdneQdRdB C D E F G

88 self._size = 0 2H I J :c;c=cQeReSeg h i j u v w x y z A (d)d*d8c9c!cK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 SdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o +d,d.c^cTe,c_cVc4cWc-cXcYcZc0c5cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb6c7c7bUc8b-d.d/d`c{c|c}c~cadbdcdddedfdgdhd1cSc/cfc2cTc9bOc3cbccc6bdcr 2dgcoepeqereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNe=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele#d$d:d;dOePe%d'dUeVeidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeWeXeOdPdneQdRdB C D E F G

89 self._memory_resource = None 2H I J :c;c=cQeReSeg h i j u v w x y z A (d)d*d8c9c!cK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 SdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o +d,d.c^cTe,c_cVc4cWc-cXcYcZc0c5cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb6c7c7bUc8b-d.d/d`c{c|c}c~cadbdcdddedfdgdhd1cSc/cfc2cTc9bOc3cbccc6bdcr 2dgcoepeqereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNe=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele#d$d:d;dOePe%d'dUeVeidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeWeXeOdPdneQdRdB C D E F G

90 self._ipc_data = None 2H I J :c;c=cQeReSeg h i j u v w x y z A (d)d*d8c9c!cK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 SdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o +d,d.c^cTe,c_cVc4cWc-cXcYcZc0c5cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb6c7c7bUc8b-d.d/d`c{c|c}c~cadbdcdddedfdgdhd1cSc/cfc2cTc9bOc3cbccc6bdcr 2dgcoepeqereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNe=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele#d$d:d;dOePe%d'dUeVeidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeWeXeOdPdneQdRdB C D E F G

91 self._owner = None 2H I J :c;c=cQeReSeg h i j u v w x y z A (d)d*d8c9c!cK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 SdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o +d,d.c^cTe,c_cVc4cWc-cXcYcZc0c5cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb6c7c7bUc8b-d.d/d`c{c|c}c~cadbdcdddedfdgdhd1cSc/cfc2cTc9bOc3cbccc6bdcr 2dgcoepeqereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNe=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele#d$d:d;dOePe%d'dUeVeidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeWeXeOdPdneQdRdB C D E F G

92 self._mem_attrs_inited = False 2H I J :c;c=cQeReSeg h i j u v w x y z A (d)d*d8c9c!cK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 SdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o +d,d.c^cTe,c_cVc4cWc-cXcYcZc0c5cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb6c7c7bUc8b-d.d/d`c{c|c}c~cadbdcdddedfdgdhd1cSc/cfc2cTc9bOc3cbccc6bdcr 2dgcoepeqereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNe=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele#d$d:d;dOePe%d'dUeVeidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeWeXeOdPdneQdRdB C D E F G

93  

94 def __init__(self, *args, **kwargs): 

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

96 "Please use MemoryResource APIs.") 

97  

98 @classmethod 

99 def _init( 

100 cls, ptr: DevicePointerT, size_t size, mr: MemoryResource | None = None, 

101 ipc_descriptor: IPCBufferDescriptor | None = None, 

102 owner : object | None = None 

103 ): 

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

105  

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

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

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

109 """ 

110 if mr is not None and owner is not None: 2H I J g h i j u v w x y z A K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 | } ~ abbbcbdbebfbgbl m p q n o .cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb0eSc/cfc2cbccc6bdcr gcB C D E F G

111 raise ValueError("owner and memory resource cannot be both specified together") 20e

112 cdef Buffer self = Buffer.__new__(cls) 2H I J g h i j u v w x y z A K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 | } ~ abbbcbdbebfbgbl m p q n o .cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSbSc/cfc2cbccc6bdcr gcB C D E F G

113 cdef uintptr_t c_ptr = <uintptr_t>(int(ptr)) 2H I J g h i j u v w x y z A K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 | } ~ abbbcbdbebfbgbl m p q n o .cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSbSc/cfc2cbccc6bdcr gcB C D E F G

114 if mr is not None: 2H I J g h i j u v w x y z A K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 | } ~ abbbcbdbebfbgbl m p q n o .cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSbSc/cfc2cbccc6bdcr gcB C D E F G

115 self._h_ptr = deviceptr_create_with_mr(c_ptr, size, mr) 2hbH I J g h i j u v w x y z A K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 | } ~ abbbcbdbebfbgbl m p q n o .cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNcibc d lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSbSc/cfcbccc6bdcr

116 else: 

117 self._h_ptr = deviceptr_create_with_owner(c_ptr, owner) 2a b k s t c d e f 2cgcB C D E F G

118 self._size = size 2H I J g h i j u v w x y z A K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 | } ~ abbbcbdbebfbgbl m p q n o .cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSbSc/cfc2cbccc6bdcr gcB C D E F G

119 self._memory_resource = mr 2H I J g h i j u v w x y z A K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 | } ~ abbbcbdbebfbgbl m p q n o .cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSbSc/cfc2cbccc6bdcr gcB C D E F G

120 self._ipc_data = IPCDataForBuffer(ipc_descriptor, True) if ipc_descriptor is not None else None 2H I J g h i j u v w x y z A K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 | } ~ abbbcbdbebfbgbl m p q n o .cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSbSc/cfc2cbccc6bdcr gcB C D E F G

121 self._owner = owner 2H I J g h i j u v w x y z A K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 | } ~ abbbcbdbebfbgbl m p q n o .cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSbSc/cfc2cbccc6bdcr gcB C D E F G

122 self._mem_attrs_inited = False 2H I J g h i j u v w x y z A K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 | } ~ abbbcbdbebfbgbl m p q n o .cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSbSc/cfc2cbccc6bdcr gcB C D E F G

123 return self 2H I J g h i j u v w x y z A K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 | } ~ abbbcbdbebfbgbl m p q n o .cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSbSc/cfc2cbccc6bdcr gcB C D E F G

124  

125 @staticmethod 

126 def _reduce_helper(mr, ipc_descriptor): 

127 return Buffer.from_ipc_descriptor(mr, ipc_descriptor) 

128  

129 def __reduce__(self): 

130 # Must not serialize the parent's stream! 

131 return Buffer._reduce_helper, (self.memory_resource, self.get_ipc_descriptor()) 2SdTdUdVd| } WdXdYdZd0d1d#c$c%c'c~ abbbcbdbebfbgb(c)c*c+cl m n o

132  

133 @staticmethod 

134 def from_handle( 

135 ptr: DevicePointerT, size_t size, mr: MemoryResource | None = None, 

136 owner: object | None = None, 

137 ) -> Buffer: 

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

139  

140 Parameters 

141 ---------- 

142 ptr : :obj:`~_memory.DevicePointerT` 

143 Allocated buffer handle object 

144 size : int 

145 Memory size of the buffer 

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

147 Memory resource associated with the buffer. When provided, 

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

149 closed or garbage collected. 

150 owner : object, optional 

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

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

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

154  

155 Note 

156 ---- 

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

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

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

160 """ 

161 return Buffer._init(ptr, size, mr=mr, owner=owner) 2g h i j u v w x y z A | } ~ abbbcbdbebfbgbl m p q n o PcQcRchc5bRbecicjckcMcNciba b k s t c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb0eSc/cfc2cbccc6bdcgcB C D E F G

162  

163 @classmethod 

164 def from_ipc_descriptor( 

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

166 stream: Stream = None 

167 ) -> Buffer: 

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

169 return _ipc.Buffer_from_ipc_descriptor(cls, mr, ipc_descriptor, stream) 21c3c

170  

171 def get_ipc_descriptor(self) -> IPCBufferDescriptor: 

172 """Export a buffer allocated for sharing between processes.""" 

173 if self._ipc_data is None: 2SdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o 1cOc3c#d$d

174 self._ipc_data = IPCDataForBuffer(_ipc.Buffer_get_ipc_descriptor(self), False) 2SdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o 1cOc3c#d$d

175 return self._ipc_data.ipc_descriptor 2SdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o Oc#d$d

176  

177 def close(self, stream: Stream | GraphBuilder | None = None): 

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

179  

180 This buffer is released back to their memory resource 

181 asynchronously on the given stream. 

182  

183 Parameters 

184 ---------- 

185 stream : :obj:`~_stream.Stream` | :obj:`~_graph.GraphBuilder`, optional 

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

187 the deallocation stream stored in the handle is used. 

188 """ 

189 Buffer_close(self, stream) 2H I J :c;c=cg h i j u v w x y z A 8c9c!cK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 l m p q n o ^c,c_cVc4cWc-cXcYcZc0c5chc5bRba b k c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb6c7c7bUc8b`c{c|c}c~cadbdcdddedfdgdhd1cScfc2cTc9bOc3cbccc6bdc

190  

191 def __enter__(self): 

192 return self 2Vc4cWcYcZc0c5c

193  

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

195 self.close() 2Vc4cWcYcZc0c5c

196 return False 2Vc4cWcYcZc0c5c

197  

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

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

200  

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

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

203 allocated using the associated memory resource before the copy. 

204  

205 Parameters 

206 ---------- 

207 dst : :obj:`~_memory.Buffer` 

208 Source buffer to copy data from 

209 stream : :obj:`~_stream.Stream` | :obj:`~_graph.GraphBuilder` 

210 Keyword argument specifying the stream for the 

211 asynchronous copy 

212  

213 """ 

214 cdef Stream s = Stream_accept(stream) 2Rb7b8b9br

215 cdef size_t src_size = self._size 2Rb7b8b9br

216  

217 if dst is None: 2Rb7b8b9br

218 if self._memory_resource is None: 

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

220 "buffer does not have a memory_resource)") 

221 dst = self._memory_resource.allocate(src_size, s) 

222  

223 cdef size_t dst_size = dst._size 2Rb7b8b9br

224 if dst_size != src_size: 2Rb7b8b9br

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

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

227 ) 

228 with nogil: 2Rb7b8b9br

229 HANDLE_RETURN(cydriver.cuMemcpyAsync( 2Rb7b8b9br

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

231 return dst 2Rb7b8b9br

232  

233 def copy_from(self, src: Buffer, *, stream: Stream | GraphBuilder): 

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

235  

236 Parameters 

237 ---------- 

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

239 Source buffer to copy data from 

240 stream : :obj:`~_stream.Stream` | :obj:`~_graph.GraphBuilder` 

241 Keyword argument specifying the stream for the 

242 asynchronous copy 

243  

244 """ 

245 cdef Stream s = Stream_accept(stream) 2g h i j u v w x y z A | } ~ abbbcbdbebfbgbl m p q n o PcQcRc5b

246 cdef size_t dst_size = self._size 2g h i j u v w x y z A | } ~ abbbcbdbebfbgbl m p q n o PcQcRc5b

247 cdef size_t src_size = src._size 2g h i j u v w x y z A | } ~ abbbcbdbebfbgbl m p q n o PcQcRc5b

248  

249 if src_size != dst_size: 2g h i j u v w x y z A | } ~ abbbcbdbebfbgbl m p q n o PcQcRc5b

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

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

252 ) 

253 with nogil: 2g h i j u v w x y z A | } ~ abbbcbdbebfbgbl m p q n o PcQcRc5b

254 HANDLE_RETURN(cydriver.cuMemcpyAsync( 2g h i j u v w x y z A | } ~ abbbcbdbebfbgbl m p q n o PcQcRc5b

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

256  

257 def fill(self, value: int | BufferProtocol, *, stream: Stream | GraphBuilder): 

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

259  

260 Parameters 

261 ---------- 

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

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

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

265 stream : :obj:`~_stream.Stream` | :obj:`~_graph.GraphBuilder` 

266 Stream for the asynchronous fill operation. 

267  

268 Raises 

269 ------ 

270 TypeError 

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

272 ValueError 

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

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

275 OverflowError 

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

277  

278 """ 

279 cdef Stream s_stream = Stream_accept(stream) 2g h i j lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLc

280 cdef unsigned int val 

281 cdef unsigned int elem_size 

282 val, elem_size = _parse_fill_value(value) 2g h i j lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLc

283  

284 cdef size_t buffer_size = self._size 2g h i j KbTbjbUbkbLblbMbNbObmbnbobpbqbrbPbQbsbtbVbubvbWbwbXb8 Yb9 xb! ybzbAb# $ % ' ( ) BbCb* + Zb, - 0bDb1b. 2b/ Eb: FbGbHb; = ? @ [ ] IbJb^ _ 3b` { 4b

285 cdef cydriver.CUdeviceptr dst = as_cu(self._h_ptr) 2g h i j KbTbjbUbkbLblbMbNbObmbnbobpbqbrbPbQbsbtbVbubvbWbwbXb8 Yb9 xb! ybzbAb# $ % ' ( ) BbCb* + Zb, - 0bDb1b. 2b/ Eb: FbGbHb; = ? @ [ ] IbJb^ _ 3b` { 4b

286 cdef cydriver.CUstream s = as_cu(s_stream._h_stream) 2g h i j KbTbjbUbkbLblbMbNbObmbnbobpbqbrbPbQbsbtbVbubvbWbwbXb8 Yb9 xb! ybzbAb# $ % ' ( ) BbCb* + Zb, - 0bDb1b. 2b/ Eb: FbGbHb; = ? @ [ ] IbJb^ _ 3b` { 4b

287  

288 if elem_size == 1: 2g h i j KbTbjbUbkbLblbMbNbObmbnbobpbqbrbPbQbsbtbVbubvbWbwbXb8 Yb9 xb! ybzbAb# $ % ' ( ) BbCb* + Zb, - 0bDb1b. 2b/ Eb: FbGbHb; = ? @ [ ] IbJb^ _ 3b` { 4b

289 with nogil: 2g h i j KbLbMbNbObPbQbwbxbybzbAbBbCbDbEbFbGbHbIbJb

290 HANDLE_RETURN(cydriver.cuMemsetD8Async(dst, val, buffer_size, s)) 2g h i j KbLbMbNbObPbQbwbxbybzbAbBbCbDbEbFbGbHbIbJb

291 elif elem_size == 2: 

292 if buffer_size & 0x1: 2TbjbmbnbobsbtbVbXb8 # $ % * + Zb1b. ; = ? ^ _ 3b

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

294 with nogil: 2jbmbnbobsbtb8 # $ % * + . ; = ? ^ _

295 HANDLE_RETURN(cydriver.cuMemsetD16Async(dst, val, buffer_size // 2, s)) 2jbmbnbobsbtb8 # $ % * + . ; = ? ^ _

296 elif elem_size == 4: 

297 if buffer_size & 0x3: 2UbkblbpbqbrbubvbWbYb9 ! ' ( ) , - 0b2b/ : @ [ ] ` { 4b

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

299 with nogil: 2kblbpbqbrbubvb9 ! ' ( ) , - / : @ [ ] ` {

300 HANDLE_RETURN(cydriver.cuMemsetD32Async(dst, val, buffer_size // 4, s)) 2kblbpbqbrbubvb9 ! ' ( ) , - / : @ [ ] ` {

301  

302 def __dlpack__( 

303 self, 

304 *, 

305 stream: int | None = None, 

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

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

308 copy: bool | None = None, 

309 ) -> TypeVar("PyCapsule"): 

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

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

312 if dl_device is not None: 2H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 !b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacecibr

313 raise BufferError("Sorry, not supported: dl_device other than None") 2ib

314 if copy is True: 2H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 !b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacecibr

315 raise BufferError("Sorry, not supported: copy=True") 2ib

316 if max_version is None: 2H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 !b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacecibr

317 versioned = False 2ecib

318 else: 

319 if not isinstance(max_version, tuple) or len(max_version) != 2: 2H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 !b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacibr

320 raise BufferError(f"Expected max_version tuple[int, int], got {max_version}") 2ib

321 versioned = max_version >= (1, 0) 2H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 !b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacibr

322 capsule = make_py_capsule(self, versioned) 2H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 !b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacecibr

323 return capsule 2H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 !b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacibr

324  

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

326 cdef bint d = self.is_device_accessible 2icjckcMcNc

327 cdef bint h = self.is_host_accessible 2icjckcMcNc

328 if d and (not h): 2icjckcMcNc

329 return (DLDeviceType.kDLCUDA, self.device_id) 2jc

330 if d and h: 2ickcMcNc

331 # TODO: this can also be kDLCUDAManaged, we need more fine-grained checks 

332 return (DLDeviceType.kDLCUDAHost, 0) 2McNc

333 if (not d) and h: 2ickc

334 return (DLDeviceType.kDLCPU, 0) 2kc

335 raise BufferError("buffer is neither device-accessible nor host-accessible") 2ic

336  

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

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

339 # This raises a BufferError unless: 

340 # 1. Python is 3.12+ 

341 # 2. This Buffer object is host accessible 

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

343  

344 def __release_buffer__(self, buffer: memoryview, /): 

345 # Supporting method paired with __buffer__. 

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

347  

348 @property 

349 def device_id(self) -> int: 

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

351 if self._memory_resource is not None: 2(d)d*d+d,djciba b k s t c d e f 6c7c-d.d/dTcbcccdcidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdB C D E F G

352 return self._memory_resource.device_id 2(d)d*d+d,djcib6c7c-d.d/dTcbcccdcidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRd

353 _init_mem_attrs(self) 1abkstcdefBCDEFG

354 return self._mem_attrs.device_id 1abkstcdefBCDEFG

355  

356 @property 

357 def handle(self) -> DevicePointerT: 

358 """Return the buffer handle object. 

359  

360 .. caution:: 

361  

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

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

364 """ 

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

366 # that expect a raw pointer value 

367 return as_intptr(self._h_ptr) 2H I J g h i j u v w x y z A (d)d*dK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 | } ~ abbbcbdbebfbgbl m p q n o +d,d.c,cVcWcXc0cPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bachc5bRbeciba b c d wb8 9 xb! ybzbAb# $ % ' ( ) BbCb* + , - Db. / Eb: FbGbHb; = ? @ [ ] IbJb^ _ ` { Sb7b8b-d.d/d9b6bdcr 2dgcidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdB C D E F G

368  

369 def __eq__(self, other) -> bool: 

370 if not isinstance(other, Buffer): 22dgc=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele;d%d'd

371 return NotImplemented 22d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele

372 cdef Buffer other_buf = <Buffer>other 22dgc;d%d'd

373 return (as_intptr(self._h_ptr) == as_intptr(other_buf._h_ptr) and 22dgc;d%d'd

374 self._size == other_buf._size) 22dgc%d'd

375  

376 def __hash__(self) -> int: 

377 return hash((as_intptr(self._h_ptr), self._size)) 2gcoepeqereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNeOePe%d'd

378  

379 def __repr__(self) -> str: 

380 maybe_is_mapped = " is_mapped=True" if self.is_mapped else "" 2| } ?c@c#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+c:d

381 return f"<Buffer ptr={as_intptr(self._h_ptr):#x} size={self._size}{maybe_is_mapped}>" 2| } ?c@c#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+c:d

382  

383 @property 

384 def is_device_accessible(self) -> bool: 

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

386 if self._memory_resource is not None: 2H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 !b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacecicjckcMcNciba b k s t c d e f SbUcTcOcr idjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdB C D E F G

387 return self._memory_resource.is_device_accessible 2H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 !b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacecicjckcMcNcibSbUcTcOcr idjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRd

388 _init_mem_attrs(self) 1abkstcdefBCDEFG

389 return self._mem_attrs.is_device_accessible 1abkstcdefBCDEFG

390  

391 @property 

392 def is_host_accessible(self) -> bool: 

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

394 if self._memory_resource is not None: 2H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 !b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacecicjckcMcNciba b k s t c d e f KbjbkbLblbMbNbObmbnbobpbqbrbPbQbsbtbubvbwb8 9 xb! ybzbAb# $ % ' ( ) BbCb* + , - Db. / Eb: FbGbHb; = ? @ [ ] IbJb^ _ ` { SbUcTcOcr

395 return self._memory_resource.is_host_accessible 2H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 !b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacecicjckcMcNcibKbjbkbLblbMbNbObmbnbobpbqbrbPbQbsbtbubvbwb8 9 xb! ybzbAb# $ % ' ( ) BbCb* + , - Db. / Eb: FbGbHb; = ? @ [ ] IbJb^ _ ` { SbUcTcOcr

396 _init_mem_attrs(self) 1abkstcdef

397 return self._mem_attrs.is_host_accessible 1abkstcdef

398  

399 @property 

400 def is_mapped(self) -> bool: 

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

402 return getattr(self._ipc_data, "is_mapped", False) 2| } ?c@c#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cSb:d

403  

404  

405 @property 

406 def memory_resource(self) -> MemoryResource: 

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

408 return self._memory_resource 2g h i j u v w x y z A SdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o hcSb7bUc8b1cTc9bOc3cbccc#d$didjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeOdPdneQdRdB C D E F G

409  

410 @property 

411 def size(self) -> int: 

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

413 return self._size 2H I J g h i j u v w x y z A (d)d*dK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 SdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o +d,dVcWc-cXcYcZcPcQcRc!b#b$b%b'b(b)b*b+b,b-b.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacecibSb6c7c7bUc8b-d.d/dTc9bOcbccc6bdcr gc#d$didjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeOdPdneQdRd

414  

415 @property 

416 def owner(self) -> object: 

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

418 return self._owner 

419  

420  

421# Memory Attribute Query Helpers 

422# ------------------------------ 

423cdef inline void _init_mem_attrs(Buffer self): 

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

425 if not self._mem_attrs_inited: 1abkstcdefBCDEFG

426 _query_memory_attrs(self._mem_attrs, as_cu(self._h_ptr)) 1abkstcdefBCDEFG

427 self._mem_attrs_inited = True 1abkstcdefBCDEFG

428  

429  

430cdef inline int _query_memory_attrs( 

431 _MemAttrs& out, 

432 cydriver.CUdeviceptr ptr 

433) except -1 nogil: 

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

435 cdef unsigned int memory_type = 0 1abkstcdefBCDEFG

436 cdef int is_managed = 0 1abkstcdefBCDEFG

437 cdef int device_id = 0 1abkstcdefBCDEFG

438 cdef cydriver.CUpointer_attribute attrs[3] 

439 cdef uintptr_t vals[3] 

440  

441 attrs[0] = cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_MEMORY_TYPE 1abkstcdefBCDEFG

442 attrs[1] = cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_IS_MANAGED 1abkstcdefBCDEFG

443 attrs[2] = cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL 1abkstcdefBCDEFG

444 vals[0] = <uintptr_t><void*>&memory_type 1abkstcdefBCDEFG

445 vals[1] = <uintptr_t><void*>&is_managed 1abkstcdefBCDEFG

446 vals[2] = <uintptr_t><void*>&device_id 1abkstcdefBCDEFG

447  

448 cdef cydriver.CUresult ret 

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

450 if ret == cydriver.CUresult.CUDA_ERROR_NOT_INITIALIZED: 1abkstcdefBCDEFG

451 with cython.gil: 

452 # Device class handles the cuInit call internally 

453 Device() 

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

455 HANDLE_RETURN(ret) 1abkstcdefBCDEFG

456  

457 if memory_type == 0: 1abkstcdefBCDEFG

458 # unregistered host pointer 

459 out.is_host_accessible = True 1kefBCDEFG

460 out.is_device_accessible = False 1kefBCDEFG

461 out.device_id = -1 1kefBCDEFG

462 elif ( 1abstcdef

463 is_managed 1abstcdef

464 or memory_type == cydriver.CUmemorytype.CU_MEMORYTYPE_HOST 1abcdef

465 ): 

466 # Managed memory or pinned host memory 

467 out.is_host_accessible = True 1stcdef

468 out.is_device_accessible = True 1stcdef

469 out.device_id = device_id 1stcdef

470 elif memory_type == cydriver.CUmemorytype.CU_MEMORYTYPE_DEVICE: 1ab

471 out.is_host_accessible = False 1ab

472 out.is_device_accessible = True 1ab

473 out.device_id = device_id 1ab

474 else: 

475 with cython.gil: 

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

477 return 0 1abkstcdefBCDEFG

478  

479  

480cdef class MemoryResource: 

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

482 deallocation of buffers. 

483  

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

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

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

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

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

489 resource's respective property.) 

490 """ 

491  

492 def allocate(self, size_t size, stream: Stream | GraphBuilder | None = None) -> Buffer: 

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

494  

495 Parameters 

496 ---------- 

497 size : int 

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

499 stream : :obj:`~_stream.Stream` | :obj:`~_graph.GraphBuilder`, optional 

500 The stream on which to perform the allocation asynchronously. 

501 If None, it is up to each memory resource implementation to decide 

502 and document the behavior. 

503  

504 Returns 

505 ------- 

506 Buffer 

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

508 depending on the resource's properties. 

509 """ 

510 raise TypeError("MemoryResource.allocate must be implemented by subclasses.") 2Sb

511  

512 def deallocate(self, ptr: DevicePointerT, size_t size, stream: Stream | GraphBuilder | None = None): 

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

514  

515 Parameters 

516 ---------- 

517 ptr : :obj:`~_memory.DevicePointerT` 

518 The pointer or handle to the buffer to deallocate. 

519 size : int 

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

521 stream : :obj:`~_stream.Stream` | :obj:`~_graph.GraphBuilder`, optional 

522 The stream on which to perform the deallocation asynchronously. 

523 If None, it is up to each memory resource implementation to decide 

524 and document the behavior. 

525 """ 

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

527  

528 @property 

529 def is_device_accessible(self) -> bool: 

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

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

532  

533 @property 

534 def is_host_accessible(self) -> bool: 

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

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

537  

538 @property 

539 def device_id(self) -> int: 

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

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

542  

543  

544# Buffer Implementation Helpers 

545# ----------------------------- 

546cdef inline Buffer Buffer_from_deviceptr_handle( 

547 DevicePtrHandle h_ptr, 

548 size_t size, 

549 MemoryResource mr, 

550 object ipc_descriptor = None 

551): 

552 """Create a Buffer from an existing DevicePtrHandle.""" 

553 cdef Buffer buf = Buffer.__new__(Buffer) 2:c;c=cQeReSeg h i j u v w x y z A (d)d*d8c9c!cSdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o +d,d^cTe,c_cVc4cWc-cXcYcZc0c5ca b 6c7c7bUc8b-d.d/d`c{c|c}c~cadbdcdddedfdgdhd1cTc9bOc3cr 2dgcoepeqereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNe=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele#d$d:d;dOePe%d'dUeVeidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeWeXeOdPdneQdRd

554 buf._h_ptr = h_ptr 2:c;c=cQeReSeg h i j u v w x y z A (d)d*d8c9c!cSdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o +d,d^cTe,c_cVc4cWc-cXcYcZc0c5ca b 6c7c7bUc8b-d.d/d`c{c|c}c~cadbdcdddedfdgdhd1cTc9bOc3cr 2dgcoepeqereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNe=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele#d$d:d;dOePe%d'dUeVeidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeWeXeOdPdneQdRd

555 buf._size = size 2:c;c=cQeReSeg h i j u v w x y z A (d)d*d8c9c!cSdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o +d,d^cTe,c_cVc4cWc-cXcYcZc0c5ca b 6c7c7bUc8b-d.d/d`c{c|c}c~cadbdcdddedfdgdhd1cTc9bOc3cr 2dgcoepeqereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNe=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele#d$d:d;dOePe%d'dUeVeidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeWeXeOdPdneQdRd

556 buf._memory_resource = mr 2:c;c=cQeReSeg h i j u v w x y z A (d)d*d8c9c!cSdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o +d,d^cTe,c_cVc4cWc-cXcYcZc0c5ca b 6c7c7bUc8b-d.d/d`c{c|c}c~cadbdcdddedfdgdhd1cTc9bOc3cr 2dgcoepeqereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNe=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele#d$d:d;dOePe%d'dUeVeidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeWeXeOdPdneQdRd

557 buf._ipc_data = IPCDataForBuffer(ipc_descriptor, True) if ipc_descriptor is not None else None 2:c;c=cQeReSeg h i j u v w x y z A (d)d*d8c9c!cSdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o +d,d^cTe,c_cVc4cWc-cXcYcZc0c5ca b 6c7c7bUc8b-d.d/d`c{c|c}c~cadbdcdddedfdgdhd1cTc9bOc3cr 2dgcoepeqereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNe=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele#d$d:d;dOePe%d'dUeVeidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeWeXeOdPdneQdRd

558 buf._owner = None 2:c;c=cQeReSeg h i j u v w x y z A (d)d*d8c9c!cSdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o +d,d^cTe,c_cVc4cWc-cXcYcZc0c5ca b 6c7c7bUc8b-d.d/d`c{c|c}c~cadbdcdddedfdgdhd1cTc9bOc3cr 2dgcoepeqereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNe=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele#d$d:d;dOePe%d'dUeVeidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeWeXeOdPdneQdRd

559 buf._mem_attrs_inited = False 2:c;c=cQeReSeg h i j u v w x y z A (d)d*d8c9c!cSdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o +d,d^cTe,c_cVc4cWc-cXcYcZc0c5ca b 6c7c7bUc8b-d.d/d`c{c|c}c~cadbdcdddedfdgdhd1cTc9bOc3cr 2dgcoepeqereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNe=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele#d$d:d;dOePe%d'dUeVeidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeWeXeOdPdneQdRd

560 return buf 2:c;c=cQeReSeg h i j u v w x y z A (d)d*d8c9c!cSdTdUdVd3d4d| } ?c@cWd5dXd6dYd7dZd8d0d9d1d!d#c$c[c]c%c'c~ abbbcbdbebfbgb(c)c*c+cl m p q n o +d,d^cTe,c_cVc4cWc-cXcYcZc0c5ca b 6c7c7bUc8b-d.d/d`c{c|c}c~cadbdcdddedfdgdhd1cTc9bOc3cr 2dgcoepeqereseteuevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeNe=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekele#d$d:d;dOePe%d'dUeVeidjdkdldmdndodpdqdrdsdtdudvdwdxdydzdAdBdCdDdEdFdGdHdIdJdKdLdMdNdmeWeXeOdPdneQdRd

561  

562  

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

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

565 cdef Stream s 

566 if not self._h_ptr: 2H I J :c;c=cg h i j u v w x y z A 8c9c!cK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 l m p q n o ^c,c_cVc4cWc-cXcYcZc0c5chc5bRba b k c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb6c7c7bUc8b`c{c|c}c~cadbdcdddedfdgdhd1cScfc2cTc9bOc3cbccc6bdc

567 return 

568 # Update deallocation stream if provided 

569 if stream is not None: 2H I J :c;c=cg h i j u v w x y z A 8c9c!cK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 l m p q n o ^c,c_cVc4cWc-cXcYcZc0c5chc5bRba b k c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb6c7c7bUc8b`c{c|c}c~cadbdcdddedfdgdhd1cScfc2cTc9bOc3cbccc6bdc

570 s = Stream_accept(stream) 28c9c!cXc7b8bfc9b

571 set_deallocation_stream(self._h_ptr, s._h_stream) 28c9c!cXc7b8bfc9b

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

573 self._h_ptr.reset() 2H I J :c;c=cg h i j u v w x y z A 8c9c!cK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 l m p q n o ^c,c_cVc4cWc-cXcYcZc0c5chc5bRba b k c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb6c7c7bUc8b`c{c|c}c~cadbdcdddedfdgdhd1cScfc2cTc9bOc3cbccc6bdc

574 self._size = 0 2H I J :c;c=cg h i j u v w x y z A 8c9c!cK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 l m p q n o ^c,c_cVc4cWc-cXcYcZc0c5chc5bRba b k c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb6c7c7bUc8b`c{c|c}c~cadbdcdddedfdgdhd1cScfc2cTc9bOc3cbccc6bdc

575 self._memory_resource = None 2H I J :c;c=cg h i j u v w x y z A 8c9c!cK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 l m p q n o ^c,c_cVc4cWc-cXcYcZc0c5chc5bRba b k c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb6c7c7bUc8b`c{c|c}c~cadbdcdddedfdgdhd1cScfc2cTc9bOc3cbccc6bdc

576 self._ipc_data = None 2H I J :c;c=cg h i j u v w x y z A 8c9c!cK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 l m p q n o ^c,c_cVc4cWc-cXcYcZc0c5chc5bRba b k c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb6c7c7bUc8b`c{c|c}c~cadbdcdddedfdgdhd1cScfc2cTc9bOc3cbccc6bdc

577 self._owner = None 2H I J :c;c=cg h i j u v w x y z A 8c9c!cK L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 l m p q n o ^c,c_cVc4cWc-cXcYcZc0c5chc5bRba b k c d e f lcmcKbTbjbncUbkbLbocpcqclbrcMbNbObmbnbobpbqbrbscPbQbsbtbVbubvbWbtcucvcwbXb8 wcYb9 xbxcyczc! AcybzbAb# $ % ' ( ) BcBbCb* + Zb, - 0bCcDcEcDb1b. Fc2b/ EbGcHcIc: JcFbGbHb; = ? @ [ ] KcIbJb^ _ 3b` { 4bLcSb6c7c7bUc8b`c{c|c}c~cadbdcdddedfdgdhd1cScfc2cTc9bOc3cbccc6bdc