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

224 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-29 01:27 +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 classify_dl_device, 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: 2b c d e 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 Q : ; = ? dbebfbgbhbibjbH I J ?c^ _ } ~ ` { dded*e4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bM N CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc. 7cfdzcvcwcrcxca

54 stream = None 2b c d e 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 Q : ; = ? dbebfbgbhbibjbH I J ?c^ _ } ~ ` { dded*e4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bM N CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc. 7cfdzcvcwcrcxca

55 if h_stream: 2b c d e 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 Q : ; = ? dbebfbgbhbibjbH I J ?c^ _ } ~ ` { dded*e4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bM N CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc. 7cfdzcvcwcrcxca

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

57 mr.deallocate(int(ptr), size, stream) 2b c d e 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 Q : ; = ? dbebfbgbhbibjbH I J ?c^ _ } ~ ` { dded*e4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bM N CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc. 7cfdzcvcwcrcxca

58 except Exception as exc: 2rc

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

60 file=sys.stderr) 2rc

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() 2b c d e 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 Q gdhdid9e!e#e: ; = ? dbebfbgbhbibjb|d}d~d@c[c]cH I J $d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { aebeddednd$ebdod%c/c'ccd(c)c*c+c:c4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc;c=csc. [ !ctccedeeepdqdrdsdtdudvdwdxdydzdAdBd,c7cfdzc| cb-c8cuc3c.cvcwcrcxca .dAcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEe^d_dfege7e8e`d{d%e'ekblbCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe(e)e8d9dGe!d#dmbnbobpbqbrbsb

85  

86 def _clear(self): 

87 self._h_ptr.reset() # Release the handle 2b c d e 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 Q gdhdid9e!e#e: ; = ? dbebfbgbhbibjb|d}d~d@c[c]cH I J $d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { aebeddednd$ebdod%c/c'ccd(c)c*c+c:c4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc;c=csc. [ !ctccedeeepdqdrdsdtdudvdwdxdydzdAdBd,c7cfdzc| cb-c8cuc3c.cvcwcrcxca .dAcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEe^d_dfege7e8e`d{d%e'ekblbCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe(e)e8d9dGe!d#dmbnbobpbqbrbsb

88 self._size = 0 2b c d e 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 Q gdhdid9e!e#e: ; = ? dbebfbgbhbibjb|d}d~d@c[c]cH I J $d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { aebeddednd$ebdod%c/c'ccd(c)c*c+c:c4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc;c=csc. [ !ctccedeeepdqdrdsdtdudvdwdxdydzdAdBd,c7cfdzc| cb-c8cuc3c.cvcwcrcxca .dAcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEe^d_dfege7e8e`d{d%e'ekblbCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe(e)e8d9dGe!d#dmbnbobpbqbrbsb

89 self._memory_resource = None 2b c d e 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 Q gdhdid9e!e#e: ; = ? dbebfbgbhbibjb|d}d~d@c[c]cH I J $d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { aebeddednd$ebdod%c/c'ccd(c)c*c+c:c4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc;c=csc. [ !ctccedeeepdqdrdsdtdudvdwdxdydzdAdBd,c7cfdzc| cb-c8cuc3c.cvcwcrcxca .dAcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEe^d_dfege7e8e`d{d%e'ekblbCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe(e)e8d9dGe!d#dmbnbobpbqbrbsb

90 self._ipc_data = None 2b c d e 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 Q gdhdid9e!e#e: ; = ? dbebfbgbhbibjb|d}d~d@c[c]cH I J $d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { aebeddednd$ebdod%c/c'ccd(c)c*c+c:c4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc;c=csc. [ !ctccedeeepdqdrdsdtdudvdwdxdydzdAdBd,c7cfdzc| cb-c8cuc3c.cvcwcrcxca .dAcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEe^d_dfege7e8e`d{d%e'ekblbCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe(e)e8d9dGe!d#dmbnbobpbqbrbsb

91 self._owner = None 2b c d e 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 Q gdhdid9e!e#e: ; = ? dbebfbgbhbibjb|d}d~d@c[c]cH I J $d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { aebeddednd$ebdod%c/c'ccd(c)c*c+c:c4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc;c=csc. [ !ctccedeeepdqdrdsdtdudvdwdxdydzdAdBd,c7cfdzc| cb-c8cuc3c.cvcwcrcxca .dAcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEe^d_dfege7e8e`d{d%e'ekblbCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe(e)e8d9dGe!d#dmbnbobpbqbrbsb

92 self._mem_attrs_inited = False 2b c d e 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 Q gdhdid9e!e#e: ; = ? dbebfbgbhbibjb|d}d~d@c[c]cH I J $d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { aebeddednd$ebdod%c/c'ccd(c)c*c+c:c4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc;c=csc. [ !ctccedeeepdqdrdsdtdudvdwdxdydzdAdBd,c7cfdzc| cb-c8cuc3c.cvcwcrcxca .dAcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEe^d_dfege7e8e`d{d%e'ekblbCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe(e)e8d9dGe!d#dmbnbobpbqbrbsb

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: 2b c d e 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 Q : ; = ? dbebfbgbhbibjbH I J TbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { dded4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc. +e7cfdzc-cvcwcrcxca Ackblbmbnbobpbqbrbsb

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

112 cdef Buffer self = Buffer.__new__(cls) 2b c d e 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 Q : ; = ? dbebfbgbhbibjbH I J TbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { dded4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc. 7cfdzc-cvcwcrcxca Ackblbmbnbobpbqbrbsb

113 cdef uintptr_t c_ptr = <uintptr_t>(int(ptr)) 2b c d e 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 Q : ; = ? dbebfbgbhbibjbH I J TbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { dded4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc. 7cfdzc-cvcwcrcxca Ackblbmbnbobpbqbrbsb

114 if mr is not None: 2b c d e 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 Q : ; = ? dbebfbgbhbibjbH I J TbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { dded4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc. 7cfdzc-cvcwcrcxca Ackblbmbnbobpbqbrbsb

115 self._h_ptr = deviceptr_create_with_mr(c_ptr, size, mr) 23bb c d e 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 Q : ; = ? dbebfbgbhbibjbH I J TbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { dded4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bM N CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc. 7cfdzcvcwcrcxca

116 else: 

117 self._h_ptr = deviceptr_create_with_owner(c_ptr, owner) 2K L / abbbM N O P -cAckblbmbnbobpbqbrbsb

118 self._size = size 2b c d e 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 Q : ; = ? dbebfbgbhbibjbH I J TbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { dded4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc. 7cfdzc-cvcwcrcxca Ackblbmbnbobpbqbrbsb

119 self._memory_resource = mr 2b c d e 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 Q : ; = ? dbebfbgbhbibjbH I J TbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { dded4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc. 7cfdzc-cvcwcrcxca Ackblbmbnbobpbqbrbsb

120 self._ipc_data = IPCDataForBuffer(ipc_descriptor, True) if ipc_descriptor is not None else None 2b c d e 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 Q : ; = ? dbebfbgbhbibjbH I J TbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { dded4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc. 7cfdzc-cvcwcrcxca Ackblbmbnbobpbqbrbsb

121 self._owner = owner 2b c d e 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 Q : ; = ? dbebfbgbhbibjbH I J TbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { dded4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc. 7cfdzc-cvcwcrcxca Ackblbmbnbobpbqbrbsb

122 self._mem_attrs_inited = False 2b c d e 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 Q : ; = ? dbebfbgbhbibjbH I J TbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { dded4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc. 7cfdzc-cvcwcrcxca Ackblbmbnbobpbqbrbsb

123 return self 2b c d e 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 Q : ; = ? dbebfbgbhbibjbH I J TbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { dded4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc. 7cfdzc-cvcwcrcxca Ackblbmbnbobpbqbrbsb

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()) 2$d%d'd(dTbUb?c)d*d+d,d-d^c_c`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ ` {

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) 2: ; = ? dbebfbgbhbibjbTbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { 4c5c6cBcqcccyc#c9c$c@ ] 4bK L / abbbM N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc. +e7cfdzc-cvcwcrcxcAckblbmbnbobpbqbrbsb

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) 2,c.c

170  

171 def get_ipc_descriptor(self) -> IPCBufferDescriptor: 

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

173 if self._ipc_data is None: 2$d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { ,c3c.c^d_d

174 self._ipc_data = IPCDataForBuffer(_ipc.Buffer_get_ipc_descriptor(self), False) 2$d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { ,c3c.c^d_d

175 return self._ipc_data.ipc_descriptor 2$d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { 3c^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) 2b c d e 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 gdhdid: ; = ? dbebfbgbhbibjb@c[c]cH I J ^ _ } ~ ` { ndbdod%c/c'ccd(c)c*c+c:cBcqcccK L / M N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc;c=csc!ctcpdqdrdsdtdudvdwdxdydzdAdBd,c7czc| cb-c8cuc3c.cvcwcrcxc

190  

191 def __enter__(self): 

192 return self 2%c/c'c)c*c+c:c

193  

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

195 self.close() 2%c/c'c)c*c+c:c

196 return False 2%c/c'c)c*c+c:c

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) 2ccsctcuca

215 cdef size_t src_size = self._size 2ccsctcuca

216  

217 if dst is None: 2ccsctcuca

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 2ccsctcuca

224 if dst_size != src_size: 2ccsctcuca

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

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

227 ) 

228 with nogil: 2ccsctcuca

229 HANDLE_RETURN(cydriver.cuMemcpyAsync( 2ccsctcuca

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

231 return dst 2ccsctcuca

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) 2: ; = ? dbebfbgbhbibjbTbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { 4c5c6cqc

246 cdef size_t dst_size = self._size 2: ; = ? dbebfbgbhbibjbTbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { 4c5c6cqc

247 cdef size_t src_size = src._size 2: ; = ? dbebfbgbhbibjbTbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { 4c5c6cqc

248  

249 if src_size != dst_size: 2: ; = ? dbebfbgbhbibjbTbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { 4c5c6cqc

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

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

252 ) 

253 with nogil: 2: ; = ? dbebfbgbhbibjbTbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { 4c5c6cqc

254 HANDLE_RETURN(cydriver.cuMemcpyAsync( 2: ; = ? dbebfbgbhbibjbTbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { 4c5c6cqc

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) 2: ; = ? CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2c

280 cdef unsigned int val 

281 cdef unsigned int elem_size 

282 val, elem_size = _parse_fill_value(value) 2: ; = ? CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2c

283  

284 cdef size_t buffer_size = self._size 2: ; = ? `bec5bfc6b{b7b|b}b~b8b9b!b#b$b%bacbc'b(bgc)b*bhc+bictbjcub,bvb-b.b/bwbxbybzbAbBb:b;bCbDbkcEbFblc=bmcGbncHb?bIb@b[b]bJbKbLbMbNbOb^b_bPbQbocRbSbpc

285 cdef cydriver.CUdeviceptr dst = as_cu(self._h_ptr) 2: ; = ? `bec5bfc6b{b7b|b}b~b8b9b!b#b$b%bacbc'b(bgc)b*bhc+bictbjcub,bvb-b.b/bwbxbybzbAbBb:b;bCbDbkcEbFblc=bmcGbncHb?bIb@b[b]bJbKbLbMbNbOb^b_bPbQbocRbSbpc

286 cdef cydriver.CUstream s = as_cu(s_stream._h_stream) 2: ; = ? `bec5bfc6b{b7b|b}b~b8b9b!b#b$b%bacbc'b(bgc)b*bhc+bictbjcub,bvb-b.b/bwbxbybzbAbBb:b;bCbDbkcEbFblc=bmcGbncHb?bIb@b[b]bJbKbLbMbNbOb^b_bPbQbocRbSbpc

287  

288 if elem_size == 1: 2: ; = ? `bec5bfc6b{b7b|b}b~b8b9b!b#b$b%bacbc'b(bgc)b*bhc+bictbjcub,bvb-b.b/bwbxbybzbAbBb:b;bCbDbkcEbFblc=bmcGbncHb?bIb@b[b]bJbKbLbMbNbOb^b_bPbQbocRbSbpc

289 with nogil: 2: ; = ? `b{b|b}b~bacbc+b,b-b.b/b:b;b=b?b@b[b]b^b_b

290 HANDLE_RETURN(cydriver.cuMemsetD8Async(dst, val, buffer_size, s)) 2: ; = ? `b{b|b}b~bacbc+b,b-b.b/b:b;b=b?b@b[b]b^b_b

291 elif elem_size == 2: 

292 if buffer_size & 0x1: 2ec5b8b9b!b'b(bgcictbwbxbybCbDbkcmcGbJbKbLbPbQboc

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

294 with nogil: 25b8b9b!b'b(btbwbxbybCbDbGbJbKbLbPbQb

295 HANDLE_RETURN(cydriver.cuMemsetD16Async(dst, val, buffer_size // 2, s)) 25b8b9b!b'b(btbwbxbybCbDbGbJbKbLbPbQb

296 elif elem_size == 4: 

297 if buffer_size & 0x3: 2fc6b7b#b$b%b)b*bhcjcubvbzbAbBbEbFblcncHbIbMbNbObRbSbpc

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

299 with nogil: 26b7b#b$b%b)b*bubvbzbAbBbEbFbHbIbMbNbObRbSb

300 HANDLE_RETURN(cydriver.cuMemsetD32Async(dst, val, buffer_size // 4, s)) 26b7b#b$b%b)b*bubvbzbAbBbEbFbHbIbMbNbObRbSb

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: 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - yc4b. [ a

313 raise BufferError("Sorry, not supported: dl_device other than None") 24b

314 if copy is True: 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - yc4b. [ a

315 raise BufferError("Sorry, not supported: copy=True") 24b

316 if max_version is None: 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - yc4b. [ a

317 versioned = False 2yc4b

318 else: 

319 if not isinstance(max_version, tuple) or len(max_version) != 2: 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - 4b. [ a

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

321 versioned = max_version >= (1, 0) 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - 4b. [ a

322 capsule = make_py_capsule(self, versioned) 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - yc4b. [ a

323 return capsule 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - 4b. [ a

324  

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

326 return classify_dl_device(self) 2#c9c$c@ ] . [

327  

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

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

330 # This raises a BufferError unless: 

331 # 1. Python is 3.12+ 

332 # 2. This Buffer object is host accessible 

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

334  

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

336 # Supporting method paired with __buffer__. 

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

338  

339 @property 

340 def device_id(self) -> int: 

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

342 if self._memory_resource is not None: 2|d}d~daebe9c4bK L / abbbM N O P ;c=ccedeee8cvcwcxckblbCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8d9d!d#dmbnbobpbqbrbsb

343 return self._memory_resource.device_id 2|d}d~daebe9c4b;c=ccedeee8cvcwcxcCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8d9d!d#d

344 _init_mem_attrs(self) 2K L / abbbM N O P kblbmbnbobpbqbrbsb

345 return self._mem_attrs.device_id 2K L / abbbM N O P kblbmbnbobpbqbrbsb

346  

347 @property 

348 def handle(self) -> DevicePointerT: 

349 """Return the buffer handle object. 

350  

351 .. caution:: 

352  

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

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

355 """ 

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

357 # that expect a raw pointer value 

358 return as_intptr(self._h_ptr) 2b c d e 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 Q : ; = ? dbebfbgbhbibjb|d}d~dH I J TbUbVbWbXbYbZb0b1b2b^ _ } ~ ` { aebeddedbd%c'c(c+c4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - Bcqcccyc4bK L M N +btbub,bvb-b.b/bwbxbybzbAbBb:b;bCbDbEbFb=bGbHb?bIb@b[b]bJbKbLbMbNbOb^b_bPbQbRbSbdcsc. [ tccedeeeucrcxca .dAckblbCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8d9d!d#dmbnbobpbqbrbsb

359  

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

361 if not isinstance(other, Buffer): 2.dAcheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEege`d{d

362 return NotImplemented 2.dheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEe

363 cdef Buffer other_buf = <Buffer>other 2.dAcge`d{d

364 return (as_intptr(self._h_ptr) == as_intptr(other_buf._h_ptr) and 2.dAcge`d{d

365 self._size == other_buf._size) 2.dAc`d{d

366  

367 def __hash__(self) -> int: 

368 return hash((as_intptr(self._h_ptr), self._size)) 2AcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e`d{d

369  

370 def __repr__(self) -> str: 

371 maybe_is_mapped = " is_mapped=True" if self.is_mapped else "" 2TbUbjdkd^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cadfe

372 return f"<Buffer ptr={as_intptr(self._h_ptr):#x} size={self._size}{maybe_is_mapped}>" 2TbUbjdkd^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cadfe

373  

374 @property 

375 def is_device_accessible(self) -> bool: 

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

377 if self._memory_resource is not None: 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - yc#c9c$c@ ] 4bK L / abbbM N O P dc. [ !c8c3ca kblbCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8d9d!d#dmbnbobpbqbrbsb

378 return self._memory_resource.is_device_accessible 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - yc#c9c$c@ ] 4bdc. [ !c8c3ca CdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7d8d9d!d#d

379 _init_mem_attrs(self) 2K L / abbbM N O P kblbmbnbobpbqbrbsb

380 return self._mem_attrs.is_device_accessible 2K L / abbbM N O P kblbmbnbobpbqbrbsb

381  

382 @property 

383 def is_host_accessible(self) -> bool: 

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

385 if self._memory_resource is not None: 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - yc#c9c$c@ ] 4bK L / abbbM N O P `b5b6b{b7b|b}b~b8b9b!b#b$b%bacbc'b(b)b*b+btbub,bvb-b.b/bwbxbybzbAbBb:b;bCbDbEbFb=bGbHb?bIb@b[b]bJbKbLbMbNbOb^b_bPbQbRbSbdc. [ !c8c3ca

386 return self._memory_resource.is_host_accessible 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - yc#c9c$c@ ] 4b`b5b6b{b7b|b}b~b8b9b!b#b$b%bacbc'b(b)b*b+btbub,bvb-b.b/bwbxbybzbAbBb:b;bCbDbEbFb=bGbHb?bIb@b[b]bJbKbLbMbNbOb^b_bPbQbRbSbdc. [ !c8c3ca

387 _init_mem_attrs(self) 2K L / abbbM N O P

388 return self._mem_attrs.is_host_accessible 2K L / abbbM N O P

389  

390 @property 

391 def is_managed(self) -> bool: 

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

393 _init_mem_attrs(self) 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] . [ | cba

394 if self._mem_attrs.is_managed: 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] . [ | cba

395 return True 1].[

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

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

398 return self._memory_resource is not None and self._memory_resource.is_managed 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ | cba

399  

400 @property 

401 def is_mapped(self) -> bool: 

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

403 return getattr(self._ipc_data, "is_mapped", False) 2TbUbjdkd^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~caddcfe

404  

405  

406 @property 

407 def memory_resource(self) -> MemoryResource: 

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

409 return self._memory_resource 2: ; = ? dbebfbgbhbibjb$d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { Bcdcsc!ctc,c8cuc3c.cvcwc^d_dkblbCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe8d9dGe!d#dmbnbobpbqbrbsb

410  

411 @property 

412 def size(self) -> int: 

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

414 return self._size 2b c d e 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 Q : ; = ? dbebfbgbhbibjb|d}d~dH I J $d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { aebe%c'ccd(c)c*c4c5c6cR S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - yc4bdc;c=csc. [ !ctccedeee8cuc3cvcwcrcxca Ac^d_dCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe8d9dGe!d#d

415  

416 @property 

417 def owner(self) -> object: 

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

419 return self._owner 

420  

421  

422# Memory Attribute Query Helpers 

423# ------------------------------ 

424cdef inline void _init_mem_attrs(Buffer self): 

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

426 if not self._mem_attrs_inited: 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

427 _query_memory_attrs(self._mem_attrs, as_cu(self._h_ptr)) 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

428 self._mem_attrs_inited = True 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

429  

430  

431cdef inline int _query_memory_attrs( 

432 _MemAttrs& out, 

433 cydriver.CUdeviceptr ptr 

434) except -1 nogil: 

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

436 cdef unsigned int memory_type = 0 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

437 cdef int is_managed = 0 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

438 cdef int device_id = 0 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

439 cdef cydriver.CUpointer_attribute attrs[3] 

440 cdef uintptr_t vals[3] 

441  

442 attrs[0] = cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_MEMORY_TYPE 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

443 attrs[1] = cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_IS_MANAGED 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

444 attrs[2] = cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

445 vals[0] = <uintptr_t><void*>&memory_type 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

446 vals[1] = <uintptr_t><void*>&is_managed 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

447 vals[2] = <uintptr_t><void*>&device_id 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

448  

449 cdef cydriver.CUresult ret 

450 ret = cydriver.cuPointerGetAttributes(3, attrs, <void**>vals, ptr) 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

451 if ret == cydriver.CUresult.CUDA_ERROR_NOT_INITIALIZED: 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

452 with cython.gil: 

453 # Device class handles the cuInit call internally 

454 Device() 

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

456 HANDLE_RETURN(ret) 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

457  

458 if memory_type == 0: 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

459 # unregistered host pointer 

460 out.is_host_accessible = True 2/ O P kblbmbnbobpbqbrbsb

461 out.is_device_accessible = False 2/ O P kblbmbnbobpbqbrbsb

462 out.device_id = -1 2/ O P kblbmbnbobpbqbrbsb

463 out.is_managed = False 2/ O P kblbmbnbobpbqbrbsb

464 elif ( 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L abbbM N O P . [ | cba

465 is_managed 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L abbbM N O P . [ | cba

466 or memory_type == cydriver.CUmemorytype.CU_MEMORYTYPE_HOST 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ K L M N O P | cba

467 ): 

468 # Managed memory or pinned host memory 

469 out.is_host_accessible = True 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] abbbM N O P . [ cba

470 out.is_device_accessible = True 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] abbbM N O P . [ cba

471 out.device_id = device_id 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] abbbM N O P . [ cba

472 out.is_managed = is_managed 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] abbbM N O P . [ cba

473 elif memory_type == cydriver.CUmemorytype.CU_MEMORYTYPE_DEVICE: 1KL|

474 out.is_host_accessible = False 1KL|

475 out.is_device_accessible = True 1KL|

476 out.device_id = device_id 1KL|

477 out.is_managed = False 1KL|

478 else: 

479 with cython.gil: 

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

481 return 0 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ ] K L / abbbM N O P . [ | cba kblbmbnbobpbqbrbsb

482  

483  

484cdef class MemoryResource: 

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

486 deallocation of buffers. 

487  

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

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

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

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

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

493 resource's respective property.) 

494 """ 

495  

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

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

498  

499 Parameters 

500 ---------- 

501 size : int 

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

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

504 The stream on which to perform the allocation asynchronously. 

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

506 and document the behavior. 

507  

508 Returns 

509 ------- 

510 Buffer 

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

512 depending on the resource's properties. 

513 """ 

514 raise TypeError("MemoryResource.allocate must be implemented by subclasses.") 2dc

515  

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

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

518  

519 Parameters 

520 ---------- 

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

522 The pointer or handle to the buffer to deallocate. 

523 size : int 

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

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

526 The stream on which to perform the deallocation asynchronously. 

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

528 and document the behavior. 

529 """ 

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

531  

532 @property 

533 def is_device_accessible(self) -> bool: 

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

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

536  

537 @property 

538 def is_host_accessible(self) -> bool: 

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

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

541  

542 @property 

543 def is_managed(self) -> bool: 

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

545 return False 2b c d e 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 Q H I J R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 ! # $ % ' ( ) * + , - @ | cba

546  

547 @property 

548 def device_id(self) -> int: 

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

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

551  

552  

553# Buffer Implementation Helpers 

554# ----------------------------- 

555cdef inline Buffer Buffer_from_deviceptr_handle( 

556 DevicePtrHandle h_ptr, 

557 size_t size, 

558 MemoryResource mr, 

559 object ipc_descriptor = None 

560): 

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

562 cdef Buffer buf = Buffer.__new__(Buffer) 2gdhdid9e!e#e: ; = ? dbebfbgbhbibjb|d}d~d@c[c]c$d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { aebend$ebdod%c/c'ccd(c)c*c+c:cK L ;c=csc[ !ctccedeeepdqdrdsdtdudvdwdxdydzdAdBd,c| cb8cuc3c.ca .dAcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEe^d_dfege7e8e`d{d%e'eCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe(e)e8d9dGe!d#d

563 buf._h_ptr = h_ptr 2gdhdid9e!e#e: ; = ? dbebfbgbhbibjb|d}d~d@c[c]c$d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { aebend$ebdod%c/c'ccd(c)c*c+c:cK L ;c=csc[ !ctccedeeepdqdrdsdtdudvdwdxdydzdAdBd,c| cb8cuc3c.ca .dAcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEe^d_dfege7e8e`d{d%e'eCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe(e)e8d9dGe!d#d

564 buf._size = size 2gdhdid9e!e#e: ; = ? dbebfbgbhbibjb|d}d~d@c[c]c$d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { aebend$ebdod%c/c'ccd(c)c*c+c:cK L ;c=csc[ !ctccedeeepdqdrdsdtdudvdwdxdydzdAdBd,c| cb8cuc3c.ca .dAcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEe^d_dfege7e8e`d{d%e'eCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe(e)e8d9dGe!d#d

565 buf._memory_resource = mr 2gdhdid9e!e#e: ; = ? dbebfbgbhbibjb|d}d~d@c[c]c$d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { aebend$ebdod%c/c'ccd(c)c*c+c:cK L ;c=csc[ !ctccedeeepdqdrdsdtdudvdwdxdydzdAdBd,c| cb8cuc3c.ca .dAcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEe^d_dfege7e8e`d{d%e'eCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe(e)e8d9dGe!d#d

566 buf._ipc_data = IPCDataForBuffer(ipc_descriptor, True) if ipc_descriptor is not None else None 2gdhdid9e!e#e: ; = ? dbebfbgbhbibjb|d}d~d@c[c]c$d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { aebend$ebdod%c/c'ccd(c)c*c+c:cK L ;c=csc[ !ctccedeeepdqdrdsdtdudvdwdxdydzdAdBd,c| cb8cuc3c.ca .dAcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEe^d_dfege7e8e`d{d%e'eCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe(e)e8d9dGe!d#d

567 buf._owner = None 2gdhdid9e!e#e: ; = ? dbebfbgbhbibjb|d}d~d@c[c]c$d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { aebend$ebdod%c/c'ccd(c)c*c+c:cK L ;c=csc[ !ctccedeeepdqdrdsdtdudvdwdxdydzdAdBd,c| cb8cuc3c.ca .dAcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEe^d_dfege7e8e`d{d%e'eCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe(e)e8d9dGe!d#d

568 buf._mem_attrs_inited = False 2gdhdid9e!e#e: ; = ? dbebfbgbhbibjb|d}d~d@c[c]c$d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { aebend$ebdod%c/c'ccd(c)c*c+c:cK L ;c=csc[ !ctccedeeepdqdrdsdtdudvdwdxdydzdAdBd,c| cb8cuc3c.ca .dAcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEe^d_dfege7e8e`d{d%e'eCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe(e)e8d9dGe!d#d

569 return buf 2gdhdid9e!e#e: ; = ? dbebfbgbhbibjb|d}d~d@c[c]c$d%d'd(d/d:dTbUbjdkd?c;d)d=d*d?d+d@d,d[d-d]d^c_cldmd`c{cVbWbXbYbZb0b1b2b|c}c~cad^ _ } ~ ` { aebend$ebdod%c/c'ccd(c)c*c+c:cK L ;c=csc[ !ctccedeeepdqdrdsdtdudvdwdxdydzdAdBd,c| cb8cuc3c.ca .dAcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6eheiejekelemeneoepeqereseteuevewexeyezeAeBeCeDeEe^d_dfege7e8e`d{d%e'eCdDdEdFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXdYdZd0d1d2d3d4d5d6d7dFe(e)e8d9dGe!d#d

570  

571  

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

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

574 cdef Stream s 

575 if not self._h_ptr: 2b c d e 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 gdhdid: ; = ? dbebfbgbhbibjb@c[c]cH I J ^ _ } ~ ` { ndbdod%c/c'ccd(c)c*c+c:cBcqcccK L / M N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc;c=csc!ctcpdqdrdsdtdudvdwdxdydzdAdBd,c7czc| cb-c8cuc3c.cvcwcrcxc

576 return 

577 # Update deallocation stream if provided 

578 if stream is not None: 2b c d e 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 gdhdid: ; = ? dbebfbgbhbibjb@c[c]cH I J ^ _ } ~ ` { ndbdod%c/c'ccd(c)c*c+c:cBcqcccK L / M N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc;c=csc!ctcpdqdrdsdtdudvdwdxdydzdAdBd,c7czc| cb-c8cuc3c.cvcwcrcxc

579 s = Stream_accept(stream) 2@c[c]c(csctczcuc

580 set_deallocation_stream(self._h_ptr, s._h_stream) 2@c[c]c(csctczcuc

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

582 self._h_ptr.reset() 2b c d e 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 gdhdid: ; = ? dbebfbgbhbibjb@c[c]cH I J ^ _ } ~ ` { ndbdod%c/c'ccd(c)c*c+c:cBcqcccK L / M N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc;c=csc!ctcpdqdrdsdtdudvdwdxdydzdAdBd,c7czc| cb-c8cuc3c.cvcwcrcxc

583 self._size = 0 2b c d e 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 gdhdid: ; = ? dbebfbgbhbibjb@c[c]cH I J ^ _ } ~ ` { ndbdod%c/c'ccd(c)c*c+c:cBcqcccK L / M N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc;c=csc!ctcpdqdrdsdtdudvdwdxdydzdAdBd,c7czc| cb-c8cuc3c.cvcwcrcxc

584 self._memory_resource = None 2b c d e 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 gdhdid: ; = ? dbebfbgbhbibjb@c[c]cH I J ^ _ } ~ ` { ndbdod%c/c'ccd(c)c*c+c:cBcqcccK L / M N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc;c=csc!ctcpdqdrdsdtdudvdwdxdydzdAdBd,c7czc| cb-c8cuc3c.cvcwcrcxc

585 self._ipc_data = None 2b c d e 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 gdhdid: ; = ? dbebfbgbhbibjb@c[c]cH I J ^ _ } ~ ` { ndbdod%c/c'ccd(c)c*c+c:cBcqcccK L / M N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc;c=csc!ctcpdqdrdsdtdudvdwdxdydzdAdBd,c7czc| cb-c8cuc3c.cvcwcrcxc

586 self._owner = None 2b c d e 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 gdhdid: ; = ? dbebfbgbhbibjb@c[c]cH I J ^ _ } ~ ` { ndbdod%c/c'ccd(c)c*c+c:cBcqcccK L / M N O P CcDc`bec5bEcfc6b{bFcGcHc7bIc|b}b~b8b9b!b#b$b%bJcacbc'b(bgc)b*bhcKcLcMc+bictbNcjcub,bOcPcQcvbRc-b.b/bwbxbybzbAbBbSc:b;bCbDbkcEbFblcTcUcVc=bmcGbWcncHb?bXcYcZcIb0c@b[b]bJbKbLbMbNbOb1c^b_bPbQbocRbSbpc2cdc;c=csc!ctcpdqdrdsdtdudvdwdxdydzdAdBd,c7czc| cb-c8cuc3c.cvcwcrcxc