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
« 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
5from __future__ import annotations
7cimport cython
8from libc.stdint cimport uintptr_t
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)
26from cuda.core._stream cimport Stream, Stream_accept
27from cuda.core._utils.cuda_utils cimport HANDLE_RETURN, _parse_fill_value
29import sys
30from typing import TypeVar
32if sys.version_info >= (3, 12):
33 from collections.abc import Buffer as BufferProtocol
34else:
35 BufferProtocol = object
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
42# =============================================================================
43# MR deallocation callback (invoked from C++ shared_ptr deleter)
44# =============================================================================
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
62register_mr_dealloc_callback(_mr_dealloc_callback)
65__all__ = ['Buffer', 'MemoryResource']
68DevicePointerT = driver.CUdeviceptr | int | None
69"""
70A type union of :obj:`~driver.CUdeviceptr`, `int` and `None` for hinting
71:attr:`Buffer.handle`.
72"""
74cdef class Buffer:
75 """Represent a handle to allocated memory.
77 This generic object provides a unified representation for how
78 different memory resources are to give access to their memory
79 allocations.
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
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
94 def __init__(self, *args, **kwargs):
95 raise RuntimeError("Buffer objects cannot be instantiated directly. "
96 "Please use MemoryResource APIs.")
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.
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
125 @staticmethod
126 def _reduce_helper(mr, ipc_descriptor):
127 return Buffer.from_ipc_descriptor(mr, ipc_descriptor)
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^ _ ` {
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.
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.
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
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
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
177 def close(self, stream: Stream | GraphBuilder | None = None):
178 """Deallocate this buffer asynchronously on the given stream.
180 This buffer is released back to their memory resource
181 asynchronously on the given stream.
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
191 def __enter__(self):
192 return self 2%c/c'c)c*c+c:c
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
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.
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.
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
213 """
214 cdef Stream s = Stream_accept(stream) 2ccsctcuca
215 cdef size_t src_size = self._size 2ccsctcuca
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)
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
233 def copy_from(self, src: Buffer, *, stream: Stream | GraphBuilder):
234 """Copy from the src buffer to this buffer asynchronously on the given stream.
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
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
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)))
257 def fill(self, value: int | BufferProtocol, *, stream: Stream | GraphBuilder):
258 """Fill this buffer with a repeating byte pattern.
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.
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).
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
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
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
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
325 def __dlpack_device__(self) -> tuple[int, int]:
326 return classify_dl_device(self) 2#c9c$c@ ] . [
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.")
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.")
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
347 @property
348 def handle(self) -> DevicePointerT:
349 """Return the buffer handle object.
351 .. caution::
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
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
367 def __hash__(self) -> int:
368 return hash((as_intptr(self._h_ptr), self._size)) 2AcHeIeJeKeLeMeNeOePeQeReSeTeUeVeWeXeYeZe0e1e2e3e4e5e6e7e8e`d{d
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
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
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
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
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
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
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
416 @property
417 def owner(self) -> object:
418 """Return the object holding external allocation."""
419 return self._owner
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
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]
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
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
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
484cdef class MemoryResource:
485 """Abstract base class for memory resources that manage allocation and
486 deallocation of buffers.
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 """
496 def allocate(self, size_t size, stream: Stream | GraphBuilder | None = None) -> Buffer:
497 """Allocate a buffer of the requested size.
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.
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
516 def deallocate(self, ptr: DevicePointerT, size_t size, stream: Stream | GraphBuilder | None = None):
517 """Deallocate a buffer previously allocated by this resource.
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.")
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.")
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.")
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
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.")
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
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