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

218 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-06-13 01:38 +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) 

25from cuda.core.typing import DevicePointerType 

26  

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

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

29  

30import sys 

31from typing import TYPE_CHECKING 

32  

33from cuda.core._utils.pycompat import BufferProtocol 

34from cuda.core._dlpack import classify_dl_device, make_py_capsule 

35from cuda.core._device import Device 

36  

37if TYPE_CHECKING: 

38 from cuda.core.graph import GraphBuilder 

39  

40  

41# ============================================================================= 

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

43# ============================================================================= 

44  

45cdef void _mr_dealloc_callback( 

46 object mr, 

47 cydriver.CUdeviceptr ptr, 

48 size_t size, 

49 const StreamHandle& h_stream, 

50) noexcept: 

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

52  

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

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

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

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

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

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

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

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

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

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

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

64 """ 

65 cdef Stream stream 

66 try: 2e f g h i j k l m n o p q r s t u v w x y z A B C D NfE F G H I J T [ ] ^ _ xbybzbAbBbCbDbK L M BfCfDfEfKcFfGfHf? IfJf= {cEbFbGbHbIbJb|c~ abkblbbbcb6d7da b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bP Q NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcDd; 8d/c9d'c)c*cGcHcFcIcd

67 stream = Stream._from_handle(Stream, h_stream) if h_stream else default_stream() 2e f g h i j k l m n o p q r s t u v w x y z A B C D NfE F G H I J T [ ] ^ _ xbybzbAbBbCbDbK L M BfCfDfEfKcFfGfHf? IfJf= {cEbFbGbHbIbJb|c~ abkblbbbcb6d7da b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bP Q NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcDd; 8d/c9d'c)c*cGcHcFcIcd

68 mr.deallocate(int(ptr), size, stream=stream) 2e f g h i j k l m n o p q r s t u v w x y z A B C D NfE F G H I J T [ ] ^ _ xbybzbAbBbCbDbK L M BfCfDfEfKcFfGfHf? IfJf= {cEbFbGbHbIbJb|c~ abkblbbbcb6d7da b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bP Q NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcDd; 8d/c9d'c)c*cGcHcFcIcd

69 except Exception as exc: 2Fc

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

71 file=sys.stderr) 2Fc

72  

73register_mr_dealloc_callback(_mr_dealloc_callback) 

74  

75  

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

77  

78  

79  

80  

81cdef class Buffer: 

82 """Represent a handle to allocated memory. 

83  

84 This generic object provides a unified representation for how 

85 different memory resources are to give access to their memory 

86 allocations. 

87  

88 Support for data interchange mechanisms are provided by DLPack. 

89 """ 

90 def __cinit__(self) -> None: 

91 self._clear() 2e f g h i j k l m n o p q r s t u v w x y z A B C D tdudE F G H I J T EdFdGdqfrfsf[ ] ^ _ xbybzbAbBbCbDbPeQeReqdrdsdK L M mbdb!d#d$d%dHdKc'dtfeb(duf)dvf? *d+dfbgbIdJdKdLdMd= seteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbSeTe6d7dRdwfBdSd=cgd?cCdadbdcdhda b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcidjdCcDd; { ;cDcUeVeWeTdUdVdWdXdYdZd0d1d2d3d4d5ddd8d/c9d'c} jbed+cEc(cfd)c*cGcHcFcIcd CeJc=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/eLeMeXeYeofpfNeOexfyfnbobpb,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:ezfAfoepe;eqereqbrbsbtbubvbwb

92  

93 def _clear(self) -> None: 

94 self._h_ptr.reset() # Release the handle 2e f g h i j k l m n o p q r s t u v w x y z A B C D tdudE F G H I J T EdFdGdqfrfsf[ ] ^ _ xbybzbAbBbCbDbPeQeReqdrdsdK L M mbdb!d#d$d%dHdKc'dtfeb(duf)dvf? *d+dfbgbIdJdKdLdMd= seteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbSeTe6d7dRdwfBdSd=cgd?cCdadbdcdhda b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcidjdCcDd; { ;cDcUeVeWeTdUdVdWdXdYdZd0d1d2d3d4d5ddd8d/c9d'c} jbed+cEc(cfd)c*cGcHcFcIcd CeJc=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/eLeMeXeYeofpfNeOexfyfnbobpb,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:ezfAfoepe;eqereqbrbsbtbubvbwb

95 self._size = 0 2e f g h i j k l m n o p q r s t u v w x y z A B C D tdudE F G H I J T EdFdGdqfrfsf[ ] ^ _ xbybzbAbBbCbDbPeQeReqdrdsdK L M mbdb!d#d$d%dHdKc'dtfeb(duf)dvf? *d+dfbgbIdJdKdLdMd= seteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbSeTe6d7dRdwfBdSd=cgd?cCdadbdcdhda b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcidjdCcDd; { ;cDcUeVeWeTdUdVdWdXdYdZd0d1d2d3d4d5ddd8d/c9d'c} jbed+cEc(cfd)c*cGcHcFcIcd CeJc=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/eLeMeXeYeofpfNeOexfyfnbobpb,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:ezfAfoepe;eqereqbrbsbtbubvbwb

96 self._memory_resource = None 2e f g h i j k l m n o p q r s t u v w x y z A B C D tdudE F G H I J T EdFdGdqfrfsf[ ] ^ _ xbybzbAbBbCbDbPeQeReqdrdsdK L M mbdb!d#d$d%dHdKc'dtfeb(duf)dvf? *d+dfbgbIdJdKdLdMd= seteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbSeTe6d7dRdwfBdSd=cgd?cCdadbdcdhda b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcidjdCcDd; { ;cDcUeVeWeTdUdVdWdXdYdZd0d1d2d3d4d5ddd8d/c9d'c} jbed+cEc(cfd)c*cGcHcFcIcd CeJc=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/eLeMeXeYeofpfNeOexfyfnbobpb,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:ezfAfoepe;eqereqbrbsbtbubvbwb

97 self._ipc_data = None 2e f g h i j k l m n o p q r s t u v w x y z A B C D tdudE F G H I J T EdFdGdqfrfsf[ ] ^ _ xbybzbAbBbCbDbPeQeReqdrdsdK L M mbdb!d#d$d%dHdKc'dtfeb(duf)dvf? *d+dfbgbIdJdKdLdMd= seteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbSeTe6d7dRdwfBdSd=cgd?cCdadbdcdhda b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcidjdCcDd; { ;cDcUeVeWeTdUdVdWdXdYdZd0d1d2d3d4d5ddd8d/c9d'c} jbed+cEc(cfd)c*cGcHcFcIcd CeJc=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/eLeMeXeYeofpfNeOexfyfnbobpb,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:ezfAfoepe;eqereqbrbsbtbubvbwb

98 self._owner = None 2e f g h i j k l m n o p q r s t u v w x y z A B C D tdudE F G H I J T EdFdGdqfrfsf[ ] ^ _ xbybzbAbBbCbDbPeQeReqdrdsdK L M mbdb!d#d$d%dHdKc'dtfeb(duf)dvf? *d+dfbgbIdJdKdLdMd= seteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbSeTe6d7dRdwfBdSd=cgd?cCdadbdcdhda b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcidjdCcDd; { ;cDcUeVeWeTdUdVdWdXdYdZd0d1d2d3d4d5ddd8d/c9d'c} jbed+cEc(cfd)c*cGcHcFcIcd CeJc=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/eLeMeXeYeofpfNeOexfyfnbobpb,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:ezfAfoepe;eqereqbrbsbtbubvbwb

99 self._mem_attrs_inited = False 2e f g h i j k l m n o p q r s t u v w x y z A B C D tdudE F G H I J T EdFdGdqfrfsf[ ] ^ _ xbybzbAbBbCbDbPeQeReqdrdsdK L M mbdb!d#d$d%dHdKc'dtfeb(duf)dvf? *d+dfbgbIdJdKdLdMd= seteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbSeTe6d7dRdwfBdSd=cgd?cCdadbdcdhda b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcidjdCcDd; { ;cDcUeVeWeTdUdVdWdXdYdZd0d1d2d3d4d5ddd8d/c9d'c} jbed+cEc(cfd)c*cGcHcFcIcd CeJc=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/eLeMeXeYeofpfNeOexfyfnbobpb,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:ezfAfoepe;eqereqbrbsbtbubvbwb

100  

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

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

103 "Please use MemoryResource APIs.") 

104  

105 @classmethod 

106 def _init( 

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

108 ipc_descriptor: IPCBufferDescriptor | None = None, 

109 owner : object | None = None 

110 ) -> Buffer: 

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

112  

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

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

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

116 """ 

117 if mr is not None and owner is not None: 2e f g 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 T [ ] ^ _ xbybzbAbBbCbDbK L M !d#d$d%dKc'd(d)d? *d+d= KbLbMbEbFbGbHbNbIbJb~ abkblbbbcb6d7da b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcDd; Of8d/c9d'ced)c*cGcHcFcIcd Jcnbobpbqbrbsbtbubvbwb

118 raise ValueError("owner and memory resource cannot be both specified together") 2Of

119 cdef Buffer self = Buffer.__new__(cls) 2e f g 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 T [ ] ^ _ xbybzbAbBbCbDbK L M !d#d$d%dKc'd(d)d? *d+d= KbLbMbEbFbGbHbNbIbJb~ abkblbbbcb6d7da b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcDd; 8d/c9d'ced)c*cGcHcFcIcd Jcnbobpbqbrbsbtbubvbwb

120 cdef uintptr_t c_ptr = <uintptr_t>(int(ptr)) 2e f g 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 T [ ] ^ _ xbybzbAbBbCbDbK L M !d#d$d%dKc'd(d)d? *d+d= KbLbMbEbFbGbHbNbIbJb~ abkblbbbcb6d7da b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcDd; 8d/c9d'ced)c*cGcHcFcIcd Jcnbobpbqbrbsbtbubvbwb

121 if mr is not None: 2e f g 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 T [ ] ^ _ xbybzbAbBbCbDbK L M !d#d$d%dKc'd(d)d? *d+d= KbLbMbEbFbGbHbNbIbJb~ abkblbbbcb6d7da b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcDd; 8d/c9d'ced)c*cGcHcFcIcd Jcnbobpbqbrbsbtbubvbwb

122 self._h_ptr = deviceptr_create_with_mr(c_ptr, size, mr) 2e f g 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 T [ ] ^ _ xbybzbAbBbCbDbK L M !d#d$d%dKc'd(d)d? *d+d= KbLbMbEbFbGbHbNbIbJb~ abkblbbbcb6d7da b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bP Q NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcDd; 8d/c9d'c)c*cGcHcFcIcd

123 else: 

124 self._h_ptr = deviceptr_create_with_owner(c_ptr, owner) 2!d#d$d%dKc'd(d)d? *d+d= N O @ hbibP Q R S edJcnbobpbqbrbsbtbubvbwb

125 self._size = size 2e f g 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 T [ ] ^ _ xbybzbAbBbCbDbK L M !d#d$d%dKc'd(d)d? *d+d= KbLbMbEbFbGbHbNbIbJb~ abkblbbbcb6d7da b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcDd; 8d/c9d'ced)c*cGcHcFcIcd Jcnbobpbqbrbsbtbubvbwb

126 self._memory_resource = mr 2e f g 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 T [ ] ^ _ xbybzbAbBbCbDbK L M !d#d$d%dKc'd(d)d? *d+d= KbLbMbEbFbGbHbNbIbJb~ abkblbbbcb6d7da b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcDd; 8d/c9d'ced)c*cGcHcFcIcd Jcnbobpbqbrbsbtbubvbwb

127 self._ipc_data = IPCDataForBuffer(ipc_descriptor, True) if ipc_descriptor is not None else None 2e f g 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 T [ ] ^ _ xbybzbAbBbCbDbK L M !d#d$d%dKc'd(d)d? *d+d= KbLbMbEbFbGbHbNbIbJb~ abkblbbbcb6d7da b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcDd; 8d/c9d'ced)c*cGcHcFcIcd Jcnbobpbqbrbsbtbubvbwb

128 self._owner = owner 2e f g 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 T [ ] ^ _ xbybzbAbBbCbDbK L M !d#d$d%dKc'd(d)d? *d+d= KbLbMbEbFbGbHbNbIbJb~ abkblbbbcb6d7da b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcDd; 8d/c9d'ced)c*cGcHcFcIcd Jcnbobpbqbrbsbtbubvbwb

129 self._mem_attrs_inited = False 2e f g 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 T [ ] ^ _ xbybzbAbBbCbDbK L M !d#d$d%dKc'd(d)d? *d+d= KbLbMbEbFbGbHbNbIbJb~ abkblbbbcb6d7da b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcDd; 8d/c9d'ced)c*cGcHcFcIcd Jcnbobpbqbrbsbtbubvbwb

130 return self 2e f g 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 T [ ] ^ _ xbybzbAbBbCbDbK L M !d#d$d%dKc'd(d)d? *d+d= KbLbMbEbFbGbHbNbIbJb~ abkblbbbcb6d7da b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcDd; 8d/c9d'ced)c*cGcHcFcIcd Jcnbobpbqbrbsbtbubvbwb

131  

132 @staticmethod 

133 def _reduce_helper(mr, ipc_descriptor): 

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

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

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

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

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

139  

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

141 # Must not serialize the parent's stream! 

142 return Buffer._reduce_helper, (self.memory_resource, self.ipc_descriptor) 2seteueveKbLbwexeyezeAeBevd{cwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abbbcb

143  

144 @staticmethod 

145 def from_handle( 

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

147 owner: object | None = None, 

148 ) -> Buffer: 

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

150  

151 Parameters 

152 ---------- 

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

154 Allocated buffer handle object 

155 size : int 

156 Memory size of the buffer 

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

158 Memory resource associated with the buffer. When provided, 

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

160 closed or garbage collected. 

161 owner : object, optional 

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

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

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

165  

166 Note 

167 ---- 

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

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

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

171 """ 

172 return Buffer._init(ptr, size, mr=mr, owner=owner) 2[ ] ^ _ xbybzbAbBbCbDb!d#d$d%dKc'd(d)d? *d+d= KbLbMbEbFbGbHbNbIbJb~ abkblbbbcb,c-c.cMcBcncLc}c:c~c` | 'bN O @ hbibP Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAc; Of8d/c9d'cedGcHcFcIcJcnbobpbqbrbsbtbubvbwb

173  

174 @classmethod 

175 def from_ipc_descriptor( 

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

177 *, stream: Stream 

178 ) -> Buffer: 

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

180  

181 Parameters 

182 ---------- 

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

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

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

186 The descriptor exported from another process. 

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

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

189 the buffer is closed or garbage collected. 

190 """ 

191 return _ipc.Buffer_from_ipc_descriptor(cls, mr, ipc_descriptor, stream) 2ddfd

192  

193 @property 

194 def ipc_descriptor(self) -> IPCBufferDescriptor: 

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

196 if self._ipc_data is None: 2seteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbdd(cfdLeMe

197 self._ipc_data = IPCDataForBuffer(_ipc.Buffer_get_ipc_descriptor(self), False) 2seteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbdd(cfdLeMe

198 return self._ipc_data.ipc_descriptor 2seteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcb(cLeMe

199  

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

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

202  

203 This buffer is released back to their memory resource 

204 asynchronously on the given stream. 

205  

206 Parameters 

207 ---------- 

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

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

210 the deallocation stream stored in the handle is used. 

211 """ 

212 Buffer_close(self, stream) 2e f g 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 EdFdGd[ ] ^ _ xbybzbAbBbCbDbqdrdsdK L M mbdbBfCfDfEfHdKcFfKfebGfLfHfMf? IfJffbgbIdJdKdLdMd= ~ abkblbbbcbRdBdSd=cgd?cCdadbdcdhdMcBcncN O @ P Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcidjdCc;cDcTdUdVdWdXdYdZd0d1d2d3d4d5ddd/c'c} jbed+cEc(cfd)c*cGcHcFcIc

213  

214 def __enter__(self): 

215 return self 2=cgd?cbdcdhd

216  

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

218 self.close() 2=cgd?cbdcdhd

219 return False 2=cgd?cbdcdhd

220  

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

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

223  

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

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

226 allocated using the associated memory resource before the copy. 

227  

228 Parameters 

229 ---------- 

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

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

232 is allocated using this buffer's memory resource. 

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

234 Keyword argument specifying the stream for the 

235 asynchronous copy 

236  

237 """ 

238 cdef Stream s = Stream_accept(stream) 2a b c ncCcDcEcd

239 cdef size_t src_size = self._size 2a b c ncCcDcEcd

240  

241 if dst is None: 2a b c ncCcDcEcd

242 if self._memory_resource is None: 

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

244 "buffer does not have a memory_resource)") 

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

246  

247 cdef size_t dst_size = dst._size 2a b c ncCcDcEcd

248 if dst_size != src_size: 2a b c ncCcDcEcd

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

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

251 ) 

252 with nogil: 2a b c ncCcDcEcd

253 HANDLE_RETURN(cydriver.cuMemcpyAsync( 2a b c ncCcDcEcd

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

255 return dst 2a b c ncCcDcEcd

256  

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

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

259  

260 Parameters 

261 ---------- 

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

263 Source buffer to copy data from 

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

265 Keyword argument specifying the stream for the 

266 asynchronous copy 

267  

268 """ 

269 cdef Stream s = Stream_accept(stream) 2[ ] ^ _ xbybzbAbBbCbDbKbLbMbEbFbGbHbNbIbJb~ abkblbbbcb,c-c.cBc

270 cdef size_t dst_size = self._size 2[ ] ^ _ xbybzbAbBbCbDbKbLbMbEbFbGbHbNbIbJb~ abkblbbbcb,c-c.cBc

271 cdef size_t src_size = src._size 2[ ] ^ _ xbybzbAbBbCbDbKbLbMbEbFbGbHbNbIbJb~ abkblbbbcb,c-c.cBc

272  

273 if src_size != dst_size: 2[ ] ^ _ xbybzbAbBbCbDbKbLbMbEbFbGbHbNbIbJb~ abkblbbbcb,c-c.cBc

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

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

276 ) 

277 with nogil: 2[ ] ^ _ xbybzbAbBbCbDbKbLbMbEbFbGbHbNbIbJb~ abkblbbbcb,c-c.cBc

278 HANDLE_RETURN(cydriver.cuMemcpyAsync( 2[ ] ^ _ xbybzbAbBbCbDbKbLbMbEbFbGbHbNbIbJb~ abkblbbbcb,c-c.cBc

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

280  

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

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

283  

284 Parameters 

285 ---------- 

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

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

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

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

290 Stream for the asynchronous fill operation. 

291  

292 Raises 

293 ------ 

294 TypeError 

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

296 ValueError 

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

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

299 OverflowError 

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

301  

302 """ 

303 cdef Stream s_stream = Stream_accept(stream) 2tdud[ ] ^ _ NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%c

304 cdef unsigned int val 

305 cdef unsigned int elem_size 

306 val, elem_size = _parse_fill_value(value) 2tdud[ ] ^ _ NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%c

307  

308 cdef size_t buffer_size = self._size 2tdud[ ] ^ _ gcoc(bpc)bhc*bicjckc+b,b-b.b/b:blcmc;b=bqc?b@brc[bscObtcPb]bQb^b_b`bRbSbTbUbVbWb{b|bXbYbucZb0bvc}bwc1bxc2b~b3bacbccc4b5b6b7b8b9bdcec!b#byc$b%bzc

309 cdef cydriver.CUdeviceptr dst = as_cu(self._h_ptr) 2tdud[ ] ^ _ gcoc(bpc)bhc*bicjckc+b,b-b.b/b:blcmc;b=bqc?b@brc[bscObtcPb]bQb^b_b`bRbSbTbUbVbWb{b|bXbYbucZb0bvc}bwc1bxc2b~b3bacbccc4b5b6b7b8b9bdcec!b#byc$b%bzc

310 cdef cydriver.CUstream s = as_cu(s_stream._h_stream) 2tdud[ ] ^ _ gcoc(bpc)bhc*bicjckc+b,b-b.b/b:blcmc;b=bqc?b@brc[bscObtcPb]bQb^b_b`bRbSbTbUbVbWb{b|bXbYbucZb0bvc}bwc1bxc2b~b3bacbccc4b5b6b7b8b9bdcec!b#byc$b%bzc

311  

312 if elem_size == 1: 2tdud[ ] ^ _ gcoc(bpc)bhc*bicjckc+b,b-b.b/b:blcmc;b=bqc?b@brc[bscObtcPb]bQb^b_b`bRbSbTbUbVbWb{b|bXbYbucZb0bvc}bwc1bxc2b~b3bacbccc4b5b6b7b8b9bdcec!b#byc$b%bzc

313 with nogil: 2tdud[ ] ^ _ gchcicjckclcmc[b]b^b_b`b{b|b}b~bacbcccdcec

314 HANDLE_RETURN(cydriver.cuMemsetD8Async(dst, val, buffer_size, s)) 2tdud[ ] ^ _ gchcicjckclcmc[b]b^b_b`b{b|b}b~bacbcccdcec

315 elif elem_size == 2: 

316 if buffer_size & 0x1: 2oc(b+b,b-b;b=bqcscObRbSbTbXbYbucwc1b4b5b6b!b#byc

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

318 with nogil: 2(b+b,b-b;b=bObRbSbTbXbYb1b4b5b6b!b#b

319 HANDLE_RETURN(cydriver.cuMemsetD16Async(dst, val, buffer_size // 2, s)) 2(b+b,b-b;b=bObRbSbTbXbYb1b4b5b6b!b#b

320 elif elem_size == 4: 

321 if buffer_size & 0x3: 2pc)b*b.b/b:b?b@brctcPbQbUbVbWbZb0bvcxc2b3b7b8b9b$b%bzc

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

323 with nogil: 2)b*b.b/b:b?b@bPbQbUbVbWbZb0b2b3b7b8b9b$b%b

324 HANDLE_RETURN(cydriver.cuMemsetD32Async(dst, val, buffer_size // 4, s)) 2)b*b.b/b:b?b@bPbQbUbVbWbZb0b2b3b7b8b9b$b%b

325  

326 def __dlpack__( 

327 self, 

328 *, 

329 stream: int | None = None, 

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

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

332 copy: bool | None = None, 

333 ) -> object: 

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

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

336 if dl_device is not None: 2e f g 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 T K L M a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : Lc'b; { d

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

338 if copy is True: 2e f g 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 T K L M a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : Lc'b; { d

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

340 if max_version is None: 2e f g 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 T K L M a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : Lc'b; { d

341 versioned = False 2Lc'b

342 else: 

343 if not isinstance(max_version, tuple) or len(max_version) != 2: 2e f g 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 T K L M a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : 'b; { d

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

345 versioned = max_version >= (1, 0) 2e f g 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 T K L M a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : 'b; { d

346 capsule = make_py_capsule(self, versioned) 2e f g 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 T K L M a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : Lc'b; { d

347 return capsule 2e f g 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 T K L M a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : 'b; { d

348  

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

350 return classify_dl_device(self) 2}c:c~c` | ; {

351  

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

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

354 # This raises a BufferError unless: 

355 # 1. Python is 3.12+ 

356 # 2. This Buffer object is host accessible 

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

358  

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

360 # Supporting method paired with __buffer__. 

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

362  

363 @property 

364 def device_id(self) -> int: 

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

366 if self._memory_resource is not None: 2PeQeReSeTe:c'bN O @ hbibP Q R S idjdUeVeWe+cGcHcIcnbobpb,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemeneoepeqereqbrbsbtbubvbwb

367 return self._memory_resource.device_id 2PeQeReSeTe:c'bidjdUeVeWe+cGcHcIc,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemeneoepeqere

368 _init_mem_attrs(self) 2N O @ hbibP Q R S nbobpbqbrbsbtbubvbwb

369 return self._mem_attrs.device_id 2N O @ hbibP Q R S nbobpbqbrbsbtbubvbwb

370  

371 @property 

372 def handle(self) -> int: 

373 """Return the buffer handle object. 

374  

375 .. caution:: 

376  

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

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

379 """ 

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

381 # that expect a raw pointer value 

382 return as_intptr(self._h_ptr) 2e f g h i j k l m n o p q r s t u v w x y z A B C D tdudE F G H I J T [ ] ^ _ xbybzbAbBbCbDbPeQeReK L M db@c!d[c#d]c$d%dKc'deb^c(d_c)d? *d`c+dfbgb= KbLbMbEbFbGbHbNbIbJb~ abkblbbbcbSeTe6d7dBd=c?cadcda b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : McBcncLc'bN O P Q [bObPb]bQb^b_b`bRbSbTbUbVbWb{b|bXbYbZb0b}b1b2b~b3bacbccc4b5b6b7b8b9bdcec!b#b$b%bAcCcDd; { DcUeVeWeEc)cFcIcd CeJcnbobpb,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemeneoepeqereqbrbsbtbubvbwb

383  

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

385 if not isinstance(other, Buffer): 2CeJcZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/eYeNeOe

386 return NotImplemented 2CeZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/e

387 cdef Buffer other_buf = <Buffer>other 2CeJcYeNeOe

388 return (as_intptr(self._h_ptr) == as_intptr(other_buf._h_ptr) and 2CeJcYeNeOe

389 self._size == other_buf._size) 2CeJcNeOe

390  

391 def __hash__(self) -> int: 

392 return hash((as_intptr(self._h_ptr), self._size)) 2Jc=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfofpfNeOe

393  

394 def __repr__(self) -> str: 

395 maybe_is_mapped = " is_mapped=True" if self.is_mapped else "" 2KbLbNdOdvd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAdXe

396 return f"<Buffer ptr={as_intptr(self._h_ptr):#x} size={self._size}{maybe_is_mapped}>" 2KbLbNdOdvd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAdXe

397  

398 @property 

399 def is_device_accessible(self) -> bool: 

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

401 if self._memory_resource is not None: 2e f g 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 T K L M a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : Lc}c:c~c` | 'bN O @ hbibP Q R S Ac; { ;c+c(cd nbobpb,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemeneoepeqereqbrbsbtbubvbwb

402 return self._memory_resource.is_device_accessible 2e f g 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 T K L M a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : Lc}c:c~c` | 'bAc; { ;c+c(cd ,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemeneoepeqere

403 _init_mem_attrs(self) 2N O @ hbibP Q R S nbobpbqbrbsbtbubvbwb

404 return self._mem_attrs.is_device_accessible 2N O @ hbibP Q R S nbobpbqbrbsbtbubvbwb

405  

406 @property 

407 def is_host_accessible(self) -> bool: 

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

409 if self._memory_resource is not None: 2e f g 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 T K L M a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : Lc}c:c~c` | 'bN O @ hbibP Q R S gc(b)bhc*bicjckc+b,b-b.b/b:blcmc;b=b?b@b[bObPb]bQb^b_b`bRbSbTbUbVbWb{b|bXbYbZb0b}b1b2b~b3bacbccc4b5b6b7b8b9bdcec!b#b$b%bAc; { ;c+c(cd

410 return self._memory_resource.is_host_accessible 2e f g 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 T K L M a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : Lc}c:c~c` | 'bgc(b)bhc*bicjckc+b,b-b.b/b:blcmc;b=b?b@b[bObPb]bQb^b_b`bRbSbTbUbVbWb{b|bXbYbZb0b}b1b2b~b3bacbccc4b5b6b7b8b9bdcec!b#b$b%bAc; { ;c+c(cd

411 _init_mem_attrs(self) 2N O @ hbibP Q R S

412 return self._mem_attrs.is_host_accessible 2N O @ hbibP Q R S

413  

414 @property 

415 def is_managed(self) -> bool: 

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

417 _init_mem_attrs(self) 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | ; { } jbd

418 if self._mem_attrs.is_managed: 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | ; { } jbd

419 return True 2mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb| ; {

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

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

422 return self._memory_resource is not None and self._memory_resource.is_managed 2e f g 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 T K L M = a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` } jbd

423  

424 @property 

425 def is_mapped(self) -> bool: 

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

427 return getattr(self._ipc_data, "is_mapped", False) 2KbLbNdOdvd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAdAcXe

428  

429  

430 @property 

431 def memory_resource(self) -> MemoryResource: 

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

433 return self._memory_resource 2[ ] ^ _ xbybzbAbBbCbDbseteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbMcAcCc;cDcdd+cEc(cfdGcHcLeMenbobpb,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:eoepe;eqereqbrbsbtbubvbwb

434  

435 @property 

436 def size(self) -> int: 

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

438 return self._size 2e f g 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 T [ ] ^ _ xbybzbAbBbCbDbPeQeReK L M db@c!d[c#d]c$d%dKc'deb^c(d_c)d? *d`c+dfbgb= seteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbSeTe=c?cCdadbda b c ,c-c.cU V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : Lc'bAcidjdCcDd; { ;cDcUeVeWe+cEc(c)cGcHcFcIcd JcLeMe,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:eoepe;eqere

439  

440 @property 

441 def owner(self) -> object: 

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

443 return self._owner 

444  

445  

446# Memory Attribute Query Helpers 

447# ------------------------------ 

448cdef inline void _init_mem_attrs(Buffer self): 

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

450 if not self._mem_attrs_inited: 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

451 _query_memory_attrs(self._mem_attrs, as_cu(self._h_ptr)) 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

452 self._mem_attrs_inited = True 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

453  

454  

455cdef inline int _query_memory_attrs( 

456 _MemAttrs& out, 

457 cydriver.CUdeviceptr ptr 

458) except -1 nogil: 

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

460 cdef unsigned int memory_type = 0 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

461 cdef int is_managed = 0 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

462 cdef int device_id = 0 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

463 cdef cydriver.CUpointer_attribute attrs[3] 

464 cdef uintptr_t vals[3] 

465  

466 attrs[0] = cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_MEMORY_TYPE 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

467 attrs[1] = cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_IS_MANAGED 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

468 attrs[2] = cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

469 vals[0] = <uintptr_t><void*>&memory_type 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

470 vals[1] = <uintptr_t><void*>&is_managed 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

471 vals[2] = <uintptr_t><void*>&device_id 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

472  

473 cdef cydriver.CUresult ret 

474 ret = cydriver.cuPointerGetAttributes(3, attrs, <void**>vals, ptr) 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

475 if ret == cydriver.CUresult.CUDA_ERROR_NOT_INITIALIZED: 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

476 with cython.gil: 

477 # Device class handles the cuInit call internally 

478 Device() 

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

480 HANDLE_RETURN(ret) 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

481  

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

483 # CU_POINTER_ATTRIBUTE_IS_MANAGED query does not capture that yet. 

484 out.is_managed = is_managed != 0 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

485  

486 if memory_type == 0: 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

487 # unregistered host pointer 

488 out.is_host_accessible = True 2@ R S nbobpbqbrbsbtbubvbwb

489 out.is_device_accessible = False 2@ R S nbobpbqbrbsbtbubvbwb

490 out.device_id = -1 2@ R S nbobpbqbrbsbtbubvbwb

491 elif ( 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O hbibP Q R S ; { } jbd

492 is_managed 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O hbibP Q R S ; { } jbd

493 or memory_type == cydriver.CUmemorytype.CU_MEMORYTYPE_HOST 2e f g 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 T K L M = a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` N O P Q R S } jbd

494 ): 

495 # Managed memory or pinned host memory 

496 out.is_host_accessible = True 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgba b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | hbibP Q R S ; { jbd

497 out.is_device_accessible = True 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgba b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | hbibP Q R S ; { jbd

498 out.device_id = device_id 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgba b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | hbibP Q R S ; { jbd

499 elif memory_type == cydriver.CUmemorytype.CU_MEMORYTYPE_DEVICE: 1=NO}

500 out.is_host_accessible = False 1=NO}

501 out.is_device_accessible = True 1=NO}

502 out.device_id = device_id 1=NO}

503 else: 

504 with cython.gil: 

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

506 return 0 2e f g 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 T K L M mbdb@c[c]ckdldmdeb^c_cndod? pd`cfbgb= a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` | N O @ hbibP Q R S ; { } jbd nbobpbqbrbsbtbubvbwb

507  

508  

509cdef class MemoryResource: 

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

511 deallocation of buffers. 

512  

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

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

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

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

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

518 resource's respective property.) 

519 """ 

520  

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

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

523  

524 Parameters 

525 ---------- 

526 size : int 

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

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

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

530 asynchronously. Must be passed explicitly; pass 

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

532  

533 Returns 

534 ------- 

535 Buffer 

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

537 depending on the resource's properties. 

538 """ 

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

540  

541 def deallocate( 

542 self, 

543 ptr: DevicePointerType, 

544 size_t size, 

545 *, 

546 stream: Stream | GraphBuilder 

547 ) -> None: 

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

549  

550 Parameters 

551 ---------- 

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

553 The pointer or handle to the buffer to deallocate. 

554 size : int 

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

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

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

558 asynchronously. Must be passed explicitly; pass 

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

560 """ 

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

562  

563 @property 

564 def is_device_accessible(self) -> bool: 

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

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

567  

568 @property 

569 def is_host_accessible(self) -> bool: 

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

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

572  

573 @property 

574 def is_managed(self) -> bool: 

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

576 return False 2e f g 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 T K L M a b c U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - . / : ` } jbd

577  

578 @property 

579 def device_id(self) -> int: 

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

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

582  

583  

584# Buffer Implementation Helpers 

585# ----------------------------- 

586cdef Buffer Buffer_from_deviceptr_handle( 

587 DevicePtrHandle h_ptr, 

588 size_t size, 

589 MemoryResource mr, 

590 object ipc_descriptor = None, 

591 type cls = Buffer, 

592): 

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

594 cdef Buffer buf = cls.__new__(cls) 2tdudEdFdGdqfrfsf[ ] ^ _ xbybzbAbBbCbDbPeQeReqdrdsdmbdbHdtfebufvffbgbIdJdKdLdMdseteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbSeTeRdwfBdSd=cgd?cCdadbdcdhda b c N O idjdCc{ ;cDcUeVeWeTdUdVdWdXdYdZd0d1d2d3d4d5ddd} jb+cEc(cfdd CeJc=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/eLeMeXeYeofpfNeOexfyf,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:ezfAfoepe;eqere

595 buf._h_ptr = h_ptr 2tdudEdFdGdqfrfsf[ ] ^ _ xbybzbAbBbCbDbPeQeReqdrdsdmbdbHdtfebufvffbgbIdJdKdLdMdseteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbSeTeRdwfBdSd=cgd?cCdadbdcdhda b c N O idjdCc{ ;cDcUeVeWeTdUdVdWdXdYdZd0d1d2d3d4d5ddd} jb+cEc(cfdd CeJc=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/eLeMeXeYeofpfNeOexfyf,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:ezfAfoepe;eqere

596 buf._size = size 2tdudEdFdGdqfrfsf[ ] ^ _ xbybzbAbBbCbDbPeQeReqdrdsdmbdbHdtfebufvffbgbIdJdKdLdMdseteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbSeTeRdwfBdSd=cgd?cCdadbdcdhda b c N O idjdCc{ ;cDcUeVeWeTdUdVdWdXdYdZd0d1d2d3d4d5ddd} jb+cEc(cfdd CeJc=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/eLeMeXeYeofpfNeOexfyf,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:ezfAfoepe;eqere

597 buf._memory_resource = mr 2tdudEdFdGdqfrfsf[ ] ^ _ xbybzbAbBbCbDbPeQeReqdrdsdmbdbHdtfebufvffbgbIdJdKdLdMdseteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbSeTeRdwfBdSd=cgd?cCdadbdcdhda b c N O idjdCc{ ;cDcUeVeWeTdUdVdWdXdYdZd0d1d2d3d4d5ddd} jb+cEc(cfdd CeJc=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/eLeMeXeYeofpfNeOexfyf,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:ezfAfoepe;eqere

598 buf._ipc_data = IPCDataForBuffer(ipc_descriptor, True) if ipc_descriptor is not None else None 2tdudEdFdGdqfrfsf[ ] ^ _ xbybzbAbBbCbDbPeQeReqdrdsdmbdbHdtfebufvffbgbIdJdKdLdMdseteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbSeTeRdwfBdSd=cgd?cCdadbdcdhda b c N O idjdCc{ ;cDcUeVeWeTdUdVdWdXdYdZd0d1d2d3d4d5ddd} jb+cEc(cfdd CeJc=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/eLeMeXeYeofpfNeOexfyf,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:ezfAfoepe;eqere

599 buf._owner = None 2tdudEdFdGdqfrfsf[ ] ^ _ xbybzbAbBbCbDbPeQeReqdrdsdmbdbHdtfebufvffbgbIdJdKdLdMdseteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbSeTeRdwfBdSd=cgd?cCdadbdcdhda b c N O idjdCc{ ;cDcUeVeWeTdUdVdWdXdYdZd0d1d2d3d4d5ddd} jb+cEc(cfdd CeJc=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/eLeMeXeYeofpfNeOexfyf,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:ezfAfoepe;eqere

600 buf._mem_attrs_inited = False 2tdudEdFdGdqfrfsf[ ] ^ _ xbybzbAbBbCbDbPeQeReqdrdsdmbdbHdtfebufvffbgbIdJdKdLdMdseteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbSeTeRdwfBdSd=cgd?cCdadbdcdhda b c N O idjdCc{ ;cDcUeVeWeTdUdVdWdXdYdZd0d1d2d3d4d5ddd} jb+cEc(cfdd CeJc=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/eLeMeXeYeofpfNeOexfyf,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:ezfAfoepe;eqere

601 return buf 2tdudEdFdGdqfrfsf[ ] ^ _ xbybzbAbBbCbDbPeQeReqdrdsdmbdbHdtfebufvffbgbIdJdKdLdMdseteueveDeEeKbLbNdOdweFexeGeyeHezeIeAeJeBeKevd{cPdQdwdxdMbEbFbGbHbNbIbJb|cydzdAd~ abkblbbbcbSeTeRdwfBdSd=cgd?cCdadbdcdhda b c N O idjdCc{ ;cDcUeVeWeTdUdVdWdXdYdZd0d1d2d3d4d5ddd} jb+cEc(cfdd CeJc=e?e@e[e]e^e_e`e{e|e}e~eafbfcfdfefffgfhfifjfkflfmfnfZe0e1e2e3e4e5e6e7e8e9e!e#e$e%e'e(e)e*e+e,e-e.e/eLeMeXeYeofpfNeOexfyf,d-d.d/d:d;d=d?d@d[d]d^d_d`d{d|d}d~daebecedeeefegeheiejekelemene:ezfAfoepe;eqere

602  

603  

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

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

606 cdef Stream s 

607 if not self._h_ptr: 2e f g 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 EdFdGd[ ] ^ _ xbybzbAbBbCbDbqdrdsdK L M mbdbBfCfDfEfHdKcFfKfebGfLfHfMf? IfJffbgbIdJdKdLdMd= ~ abkblbbbcbRdBdSd=cgd?cCdadbdcdhdMcBcncN O @ P Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcidjdCc;cDcTdUdVdWdXdYdZd0d1d2d3d4d5ddd/c'c} jbed+cEc(cfd)c*cGcHcFcIc

608 return 

609 # Update deallocation stream if provided 

610 if stream is not None: 2e f g 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 EdFdGd[ ] ^ _ xbybzbAbBbCbDbqdrdsdK L M mbdbBfCfDfEfHdKcFfKfebGfLfHfMf? IfJffbgbIdJdKdLdMd= ~ abkblbbbcbRdBdSd=cgd?cCdadbdcdhdMcBcncN O @ P Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcidjdCc;cDcTdUdVdWdXdYdZd0d1d2d3d4d5ddd/c'c} jbed+cEc(cfd)c*cGcHcFcIc

611 s = Stream_accept(stream) 2qdrdsdadCcDc'cEc*c

612 set_deallocation_stream(self._h_ptr, s._h_stream) 2qdrdsdadCcDc'cEc*c

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

614 self._h_ptr.reset() 2e f g 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 EdFdGd[ ] ^ _ xbybzbAbBbCbDbqdrdsdK L M mbdbBfCfDfEfHdKcFfKfebGfLfHfMf? IfJffbgbIdJdKdLdMd= ~ abkblbbbcbRdBdSd=cgd?cCdadbdcdhdMcBcncN O @ P Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcidjdCc;cDcTdUdVdWdXdYdZd0d1d2d3d4d5ddd/c'c} jbed+cEc(cfd)c*cGcHcFcIc

615 self._size = 0 2e f g 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 EdFdGd[ ] ^ _ xbybzbAbBbCbDbqdrdsdK L M mbdbBfCfDfEfHdKcFfKfebGfLfHfMf? IfJffbgbIdJdKdLdMd= ~ abkblbbbcbRdBdSd=cgd?cCdadbdcdhdMcBcncN O @ P Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcidjdCc;cDcTdUdVdWdXdYdZd0d1d2d3d4d5ddd/c'c} jbed+cEc(cfd)c*cGcHcFcIc

616 self._memory_resource = None 2e f g 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 EdFdGd[ ] ^ _ xbybzbAbBbCbDbqdrdsdK L M mbdbBfCfDfEfHdKcFfKfebGfLfHfMf? IfJffbgbIdJdKdLdMd= ~ abkblbbbcbRdBdSd=cgd?cCdadbdcdhdMcBcncN O @ P Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcidjdCc;cDcTdUdVdWdXdYdZd0d1d2d3d4d5ddd/c'c} jbed+cEc(cfd)c*cGcHcFcIc

617 self._ipc_data = None 2e f g 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 EdFdGd[ ] ^ _ xbybzbAbBbCbDbqdrdsdK L M mbdbBfCfDfEfHdKcFfKfebGfLfHfMf? IfJffbgbIdJdKdLdMd= ~ abkblbbbcbRdBdSd=cgd?cCdadbdcdhdMcBcncN O @ P Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcidjdCc;cDcTdUdVdWdXdYdZd0d1d2d3d4d5ddd/c'c} jbed+cEc(cfd)c*cGcHcFcIc

618 self._owner = None 2e f g 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 EdFdGd[ ] ^ _ xbybzbAbBbCbDbqdrdsdK L M mbdbBfCfDfEfHdKcFfKfebGfLfHfMf? IfJffbgbIdJdKdLdMd= ~ abkblbbbcbRdBdSd=cgd?cCdadbdcdhdMcBcncN O @ P Q R S NcOcgcoc(bPcpc)bhcQcRcSc*bTcicjckc+b,b-b.b/b:bUclcmc;b=bqc?b@brcVcWcXc[bscObYctcPb]bZc0c1cQb2c^b_b`bRbSbTbUbVbWb3c{b|bXbYbucZb0bvc4c5c6c}bwc1b7cxc2b~b8c9c!c3b#cacbccc4b5b6b7b8b9b$cdcec!b#byc$b%bzc%cAcidjdCc;cDcTdUdVdWdXdYdZd0d1d2d3d4d5ddd/c'c} jbed+cEc(cfd)c*cGcHcFcIc