Coverage for cuda / core / _memory / _buffer.pyx: 89.54%
239 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-08 01:07 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-08 01:07 +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 uint8_t, uint16_t, uint32_t, uintptr_t
9from cpython.buffer cimport PyObject_GetBuffer, PyBuffer_Release, Py_buffer, PyBUF_SIMPLE
11from cuda.bindings cimport cydriver
12from cuda.core._memory._device_memory_resource import DeviceMemoryResource
13from cuda.core._memory._pinned_memory_resource import PinnedMemoryResource
14from cuda.core._memory._ipc cimport IPCBufferDescriptor, IPCDataForBuffer
15from cuda.core._memory cimport _ipc
16from cuda.core._resource_handles cimport (
17 DevicePtrHandle,
18 StreamHandle,
19 deviceptr_create_with_owner,
20 deviceptr_create_with_mr,
21 register_mr_dealloc_callback,
22 as_intptr,
23 as_cu,
24 set_deallocation_stream,
25)
27from cuda.core._stream cimport Stream, Stream_accept
28from cuda.core._utils.cuda_utils cimport HANDLE_RETURN
30import sys
31from typing import TypeVar
33if sys.version_info >= (3, 12):
34 from collections.abc import Buffer as BufferProtocol
35else:
36 BufferProtocol = object
38from cuda.core._dlpack import DLDeviceType, make_py_capsule
39from cuda.core._utils.cuda_utils import driver
40from cuda.core._device import Device
43# =============================================================================
44# MR deallocation callback (invoked from C++ shared_ptr deleter)
45# =============================================================================
47cdef void _mr_dealloc_callback(
48 object mr,
49 cydriver.CUdeviceptr ptr,
50 size_t size,
51 const StreamHandle& h_stream,
52) noexcept:
53 """Called by the C++ deleter to deallocate via MemoryResource.deallocate."""
54 try: 2bbcbdbg h i j Q R S T U V W ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbl m p q n o #c$cTdae|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b c d 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,badUd:c7c8cuc9cr becedeeefegeheiejekelemeneoepeqereseteuevewexeyezeAe.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc
55 stream = None 2bbcbdbg h i j Q R S T U V W ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbl m p q n o #c$cTdae|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b c d 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,badUd:c7c8cuc9cr becedeeefegeheiejekelemeneoepeqereseteuevewexeyezeAe.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc
56 if h_stream: 2bbcbdbg h i j Q R S T U V W ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbl m p q n o #c$cTdae|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b c d 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,badUd:c7c8cuc9cr becedeeefegeheiejekelemeneoepeqereseteuevewexeyezeAe.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc
57 stream = Stream._from_handle(Stream, h_stream) 2:c
58 mr.deallocate(int(ptr), size, stream) 2bbcbdbg h i j Q R S T U V W ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbl m p q n o #c$cTdae|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b c d 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,badUd:c7c8cuc9cr becedeeefegeheiejekelemeneoepeqereseteuevewexeyezeAe.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc
59 except Exception as exc: 2uc
60 print(f"Warning: mr.deallocate() failed during Buffer destruction: {exc}", 2uc
61 file=sys.stderr) 2uc
63register_mr_dealloc_callback(_mr_dealloc_callback)
66__all__ = ['Buffer', 'MemoryResource']
69DevicePointerT = driver.CUdeviceptr | int | None
70"""
71A type union of :obj:`~driver.CUdeviceptr`, `int` and `None` for hinting
72:attr:`Buffer.handle`.
73"""
75cdef class Buffer:
76 """Represent a handle to allocated memory.
78 This generic object provides a unified representation for how
79 different memory resources are to give access to their memory
80 allocations.
82 Support for data interchange mechanisms are provided by DLPack.
83 """
84 def __cinit__(self):
85 self._clear() 2bbcbdbVdWdXd|d}d~dg h i j Q R S T U V W ;d=d?dIdJdKdebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBb(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bEdFdvcgdwc_d`d{d2d3d4d5d6d7d8d9d!d#d$d%d'dqdadUd:crdbdxc`csd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
87 def _clear(self):
88 self._h_ptr.reset() # Release the handle 2bbcbdbVdWdXd|d}d~dg h i j Q R S T U V W ;d=d?dIdJdKdebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBb(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bEdFdvcgdwc_d`d{d2d3d4d5d6d7d8d9d!d#d$d%d'dqdadUd:crdbdxc`csd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
89 self._size = 0 2bbcbdbVdWdXd|d}d~dg h i j Q R S T U V W ;d=d?dIdJdKdebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBb(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bEdFdvcgdwc_d`d{d2d3d4d5d6d7d8d9d!d#d$d%d'dqdadUd:crdbdxc`csd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
90 self._memory_resource = None 2bbcbdbVdWdXd|d}d~dg h i j Q R S T U V W ;d=d?dIdJdKdebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBb(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bEdFdvcgdwc_d`d{d2d3d4d5d6d7d8d9d!d#d$d%d'dqdadUd:crdbdxc`csd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
91 self._ipc_data = None 2bbcbdbVdWdXd|d}d~dg h i j Q R S T U V W ;d=d?dIdJdKdebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBb(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bEdFdvcgdwc_d`d{d2d3d4d5d6d7d8d9d!d#d$d%d'dqdadUd:crdbdxc`csd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
92 self._owner = None 2bbcbdbVdWdXd|d}d~dg h i j Q R S T U V W ;d=d?dIdJdKdebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBb(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bEdFdvcgdwc_d`d{d2d3d4d5d6d7d8d9d!d#d$d%d'dqdadUd:crdbdxc`csd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
93 self._mem_attrs_inited = False 2bbcbdbVdWdXd|d}d~dg h i j Q R S T U V W ;d=d?dIdJdKdebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBb(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bEdFdvcgdwc_d`d{d2d3d4d5d6d7d8d9d!d#d$d%d'dqdadUd:crdbdxc`csd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
95 def __init__(self, *args, **kwargs):
96 raise RuntimeError("Buffer objects cannot be instantiated directly. "
97 "Please use MemoryResource APIs.")
99 @classmethod
100 def _init(
101 cls, ptr: DevicePointerT, size_t size, mr: MemoryResource | None = None,
102 ipc_descriptor: IPCBufferDescriptor | None = None,
103 owner : object | None = None
104 ):
105 """Create a Buffer from a raw pointer.
107 When ``mr`` is provided, the buffer takes ownership: ``mr.deallocate()``
108 is called when the buffer is closed or garbage collected. When ``owner``
109 is provided, the owner is kept alive but no deallocation is performed.
110 """
111 if mr is not None and owner is not None: 2bbcbdbg h i j Q R S T U V W ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbKbLbMbNbObPbQbRbSbTbl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bBeadUd:crd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
112 raise ValueError("owner and memory resource cannot be both specified together") 2Be
113 cdef Buffer self = Buffer.__new__(cls) 2bbcbdbg h i j Q R S T U V W ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbKbLbMbNbObPbQbRbSbTbl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,badUd:crd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
114 cdef uintptr_t c_ptr = <uintptr_t>(int(ptr)) 2bbcbdbg h i j Q R S T U V W ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbKbLbMbNbObPbQbRbSbTbl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,badUd:crd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
115 if mr is not None: 2Ubbbcbdbg h i j Q R S T U V W ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbKbLbMbNbObPbQbRbSbTbl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,badUd:crd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
116 self._h_ptr = deviceptr_create_with_mr(c_ptr, size, mr) 2bbcbdbg h i j Q R S T U V W ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbKbLbMbNbObPbQbRbSbTbl m p q n o #c$cTd|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b c d 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,badUd:c7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc
117 else:
118 self._h_ptr = deviceptr_create_with_owner(c_ptr, owner) 2@d[d]d/d,d:d^da b k s t c d e f rd!c@ [ ] ^ _ `
119 self._size = size 2bbcbdbg h i j Q R S T U V W ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbKbLbMbNbObPbQbRbSbTbl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,badUd:crd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
120 self._memory_resource = mr 2bbcbdbg h i j Q R S T U V W ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbKbLbMbNbObPbQbRbSbTbl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,badUd:crd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
121 self._ipc_data = IPCDataForBuffer(ipc_descriptor, True) if ipc_descriptor is not None else None 2bbcbdbg h i j Q R S T U V W ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbKbLbMbNbObPbQbRbSbTbl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,badUd:crd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
122 self._owner = owner 2bbcbdbg h i j Q R S T U V W ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbKbLbMbNbObPbQbRbSbTbl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,badUd:crd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
123 self._mem_attrs_inited = False 2bbcbdbg h i j Q R S T U V W ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbKbLbMbNbObPbQbRbSbTbl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,badUd:crd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
124 return self 2bbcbdbg h i j Q R S T U V W ebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbKbLbMbNbObPbQbRbSbTbl m p q n o #c$cTd@d[d]d/d,d:d^d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,badUd:crd7c8cuc9cr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc@ [ ] ^ _ `
126 @staticmethod
127 def _reduce_helper(mr, ipc_descriptor):
128 return Buffer.from_ipc_descriptor(mr, ipc_descriptor)
130 def __reduce__(self):
131 # Must not serialize the parent's stream!
132 return Buffer._reduce_helper, (self.memory_resource, self.get_ipc_descriptor()) 2(d)d*d+dKbLbLdMdNdOdMbNbObPbQbRbSbTbPdQdRdSdl m n o
134 @staticmethod
135 def from_handle(
136 ptr: DevicePointerT, size_t size, mr: MemoryResource | None = None,
137 owner: object | None = None,
138 ) -> Buffer:
139 """Create a new :class:`Buffer` object from a pointer.
141 Parameters
142 ----------
143 ptr : :obj:`~_memory.DevicePointerT`
144 Allocated buffer handle object
145 size : int
146 Memory size of the buffer
147 mr : :obj:`~_memory.MemoryResource`, optional
148 Memory resource associated with the buffer. When provided,
149 :meth:`MemoryResource.deallocate` is called when the buffer is
150 closed or garbage collected.
151 owner : object, optional
152 An object holding external allocation that the ``ptr`` points to.
153 The reference is kept as long as the buffer is alive.
154 The ``owner`` and ``mr`` cannot be specified together.
156 Note
157 ----
158 When neither ``mr`` nor ``owner`` is specified, this creates a
159 non-owning reference. The pointer will NOT be freed when the
160 :class:`Buffer` is closed or garbage collected.
161 """
162 return Buffer._init(ptr, size, mr=mr, owner=owner) 2g h i j Q R S T U V W KbLbMbNbObPbQbRbSbTbl m p q n o @d[d]d/d,d:d^d|c}c~c;c-b$b%c=c?c@c[c]cVba b k s t c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bBeadUd:crd7c8cuc9c!c@ [ ] ^ _ `
164 @classmethod
165 def from_ipc_descriptor(
166 cls, mr: DeviceMemoryResource | PinnedMemoryResource, ipc_descriptor: IPCBufferDescriptor,
167 stream: Stream = None
168 ) -> Buffer:
169 """Import a buffer that was exported from another process."""
170 return _ipc.Buffer_from_ipc_descriptor(cls, mr, ipc_descriptor, stream) 2qdsd
172 def get_ipc_descriptor(self) -> IPCBufferDescriptor:
173 """Export a buffer allocated for sharing between processes."""
174 if self._ipc_data is None: 2(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o qd`csd
175 self._ipc_data = IPCDataForBuffer(_ipc.Buffer_get_ipc_descriptor(self), False) 2(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o qd`csd
176 return self._ipc_data.ipc_descriptor 2(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o `c
178 def close(self, stream: Stream | GraphBuilder | None = None):
179 """Deallocate this buffer asynchronously on the given stream.
181 This buffer is released back to their memory resource
182 asynchronously on the given stream.
184 Parameters
185 ----------
186 stream : :obj:`~_stream.Stream` | :obj:`~_graph.GraphBuilder`, optional
187 The stream object to use for asynchronous deallocation. If None,
188 the deallocation stream stored in the handle is used.
189 """
190 Buffer_close(self, stream) 2bbcbdbVdWdXdg h i j Q R S T U V W IdJdKdebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbl m p q n o ;c-b$ba b k c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bEdFdvcgdwc2d3d4d5d6d7d8d9d!d#d$d%d'dqdad:crdbdxc`csd7c8cuc9c
192 def copy_to(self, dst: Buffer = None, *, stream: Stream | GraphBuilder) -> Buffer:
193 """Copy from this buffer to the dst buffer asynchronously on the given stream.
195 Copies the data from this buffer to the provided dst buffer.
196 If the dst buffer is not provided, then a new buffer is first
197 allocated using the associated memory resource before the copy.
199 Parameters
200 ----------
201 dst : :obj:`~_memory.Buffer`
202 Source buffer to copy data from
203 stream : :obj:`~_stream.Stream` | :obj:`~_graph.GraphBuilder`
204 Keyword argument specifying the stream for the
205 asynchronous copy
207 """
208 cdef Stream s = Stream_accept(stream) 2$bvcwcxcr
209 cdef size_t src_size = self._size 2$bvcwcxcr
211 if dst is None: 2$bvcwcxcr
212 if self._memory_resource is None:
213 raise ValueError("a destination buffer must be provided (this "
214 "buffer does not have a memory_resource)")
215 dst = self._memory_resource.allocate(src_size, s)
217 cdef size_t dst_size = dst._size 2$bvcwcxcr
218 if dst_size != src_size: 2$bvcwcxcr
219 raise ValueError( "buffer sizes mismatch between src and dst (sizes "
220 f"are: src={src_size}, dst={dst_size})"
221 )
222 with nogil: 2$bvcwcxcr
223 HANDLE_RETURN(cydriver.cuMemcpyAsync( 2$bvcwcxcr
224 as_cu(dst._h_ptr), as_cu(self._h_ptr), src_size, as_cu(s._h_stream)))
225 return dst 2$bvcwcxcr
227 def copy_from(self, src: Buffer, *, stream: Stream | GraphBuilder):
228 """Copy from the src buffer to this buffer asynchronously on the given stream.
230 Parameters
231 ----------
232 src : :obj:`~_memory.Buffer`
233 Source buffer to copy data from
234 stream : :obj:`~_stream.Stream` | :obj:`~_graph.GraphBuilder`
235 Keyword argument specifying the stream for the
236 asynchronous copy
238 """
239 cdef Stream s = Stream_accept(stream) 2g h i j Q R S T U V W KbLbMbNbObPbQbRbSbTbl m p q n o |c}c~c-b
240 cdef size_t dst_size = self._size 2g h i j Q R S T U V W KbLbMbNbObPbQbRbSbTbl m p q n o |c}c~c-b
241 cdef size_t src_size = src._size 2g h i j Q R S T U V W KbLbMbNbObPbQbRbSbTbl m p q n o |c}c~c-b
243 if src_size != dst_size: 2g h i j Q R S T U V W KbLbMbNbObPbQbRbSbTbl m p q n o |c}c~c-b
244 raise ValueError( "buffer sizes mismatch between src and dst (sizes "
245 f"are: src={src_size}, dst={dst_size})"
246 )
247 with nogil: 2g h i j Q R S T U V W KbLbMbNbObPbQbRbSbTbl m p q n o |c}c~c-b
248 HANDLE_RETURN(cydriver.cuMemcpyAsync( 2g h i j Q R S T U V W KbLbMbNbObPbQbRbSbTbl m p q n o |c}c~c-b
249 as_cu(self._h_ptr), as_cu(src._h_ptr), dst_size, as_cu(s._h_stream)))
251 def fill(self, value: int | BufferProtocol, *, stream: Stream | GraphBuilder):
252 """Fill this buffer with a repeating byte pattern.
254 Parameters
255 ----------
256 value : int | :obj:`collections.abc.Buffer`
257 - int: Must be in range [0, 256). Converted to 1 byte.
258 - :obj:`collections.abc.Buffer`: Must be 1, 2, or 4 bytes.
259 stream : :obj:`~_stream.Stream` | :obj:`~_graph.GraphBuilder`
260 Stream for the asynchronous fill operation.
262 Raises
263 ------
264 TypeError
265 If value is not an int and does not support the buffer protocol.
266 ValueError
267 If value byte length is not 1, 2, or 4.
268 If buffer size is not divisible by value byte length.
269 OverflowError
270 If int value is outside [0, 256).
272 """
273 cdef Stream s_stream = Stream_accept(stream) 2g h i j 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b
275 # Handle int case: 1-byte fill with automatic overflow checking.
276 if isinstance(value, int): 2g h i j 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b
277 Buffer_fill_uint8(self, value, s_stream._h_stream) 2g h i j Wb'c(c)cEb*c+c,cHb-c.c/c
278 return 2g h i j WbEbHb
280 # Handle bytes case: direct pointer access without intermediate objects.
281 if isinstance(value, bytes): 24c%bab6b{ 'b7b| X Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; u 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? F 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b
282 Buffer_fill_from_ptr(self, <const char*><bytes>value, len(value), s_stream._h_stream) 2%bab6b{ 'b7b| (b} 8b: )b9b; *b~ !b= +b#b?
283 return 2ab{ | } : ; ~ = ?
285 # General buffer protocol path using C buffer API.
286 cdef Py_buffer buf
287 if PyObject_GetBuffer(value, &buf, PyBUF_SIMPLE) != 0: 24cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b
288 raise TypeError(
289 f"value must be an int or support the buffer protocol, got {type(value).__name__}"
290 )
291 try: 2X Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZbu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2bF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b
292 Buffer_fill_from_ptr(self, <const char*>buf.buf, buf.len, s_stream._h_stream) 2X Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZbu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2bF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b
293 finally:
294 PyBuffer_Release(&buf) 1X+,-YZ0123./4567u89!vwxyzA#$BCDEF%'(GHIJKL)*MNOP
296 def __dlpack__(
297 self,
298 *,
299 stream: int | None = None,
300 max_version: tuple[int, int] | None = None,
301 dl_device: tuple[int, int] | None = None,
302 copy: bool | None = None,
303 ) -> TypeVar("PyCapsule"):
304 # Note: we ignore the stream argument entirely (as if it is -1).
305 # It is the user's responsibility to maintain stream order.
306 if dl_device is not None: 2bbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c%cVbr
307 raise BufferError("Sorry, not supported: dl_device other than None") 2Vb
308 if copy is True: 2bbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c%cVbr
309 raise BufferError("Sorry, not supported: copy=True") 2Vb
310 if max_version is None: 2bbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c%cVbr
311 versioned = False 2%cVb
312 else:
313 if not isinstance(max_version, tuple) or len(max_version) != 2: 2bbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3cVbr
314 raise BufferError(f"Expected max_version tuple[int, int], got {max_version}") 2Vb
315 versioned = max_version >= (1, 0) 2bbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3cVbr
316 capsule = make_py_capsule(self, versioned) 2bbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c%cVbr
317 return capsule 2bbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3cVbr
319 def __dlpack_device__(self) -> tuple[int, int]:
320 cdef bint d = self.is_device_accessible 2=c?c@c[c]c
321 cdef bint h = self.is_host_accessible 2=c?c@c[c]c
322 if d and (not h): 2=c?c@c[c]c
323 return (DLDeviceType.kDLCUDA, self.device_id) 2?c
324 if d and h: 2=c@c[c]c
325 # TODO: this can also be kDLCUDAManaged, we need more fine-grained checks
326 return (DLDeviceType.kDLCUDAHost, 0) 2[c]c
327 if (not d) and h: 2=c@c
328 return (DLDeviceType.kDLCPU, 0) 2@c
329 raise BufferError("buffer is neither device-accessible nor host-accessible") 2=c
331 def __buffer__(self, flags: int, /) -> memoryview:
332 # Support for Python-level buffer protocol as per PEP 688.
333 # This raises a BufferError unless:
334 # 1. Python is 3.12+
335 # 2. This Buffer object is host accessible
336 raise NotImplementedError("WIP: Buffer.__buffer__ hasn't been implemented yet.")
338 def __release_buffer__(self, buffer: memoryview, /):
339 # Supporting method paired with __buffer__.
340 raise NotImplementedError("WIP: Buffer.__release_buffer__ hasn't been implemented yet.")
342 @property
343 def device_id(self) -> int:
344 """Return the device ordinal of this buffer."""
345 if self._memory_resource is not None: 2;d=d?d#c$c?cVba b k s t c d e f EdFd_d`d{dbd7c8c9c.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctc@ [ ] ^ _ `
346 return self._memory_resource.device_id 2;d=d?d#c$c?cVbEdFd_d`d{dbd7c8c9c.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctc
347 _init_mem_attrs(self) 1abkstcdef@[]^_`
348 return self._mem_attrs.device_id 1abkstcdef@[]^_`
350 @property
351 def handle(self) -> DevicePointerT:
352 """Return the buffer handle object.
354 .. caution::
356 This handle is a Python object. To get the memory address of the underlying C
357 handle, call ``int(Buffer.handle)``.
358 """
359 # Return raw integer for compatibility with ctypes and other tools
360 # that expect a raw pointer value
361 return as_intptr(self._h_ptr) 2bbcbdbg h i j Q R S T U V W ;d=d?debfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbKbLbMbNbObPbQbRbSbTbl m p q n o #c$cTd,d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c;c-b$b%cVba b c d } : ; Ebu 8 9 ! v w x y z A # $ B C D E ~ = ? HbF % ' ( G H I J K L ) * M N O P ,bvcwc_d`d{dxcuc9cr {c!c.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctc@ [ ] ^ _ `
363 def __eq__(self, other) -> bool:
364 if not isinstance(other, Buffer): 2{c!cjdkdldmdndodpdidcddd
365 return NotImplemented 2{cjdkdldmdndodpd
366 cdef Buffer other_buf = <Buffer>other 2{c!cidcddd
367 return (as_intptr(self._h_ptr) == as_intptr(other_buf._h_ptr) and 2{c!cidcddd
368 self._size == other_buf._size) 2{c!ccddd
370 def __hash__(self) -> int:
371 return hash((as_intptr(self._h_ptr), self._size)) 2!ctdudvdwdxdydzdAdBdCdDdcddd
373 def __repr__(self) -> str:
374 maybe_is_mapped = " is_mapped=True" if self.is_mapped else "" 2KbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdhd
375 return f"<Buffer ptr={as_intptr(self._h_ptr):#x} size={self._size}{maybe_is_mapped}>" 2KbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdhd
377 @property
378 def is_device_accessible(self) -> bool:
379 """Return True if this buffer can be accessed by the GPU, otherwise False."""
380 if self._memory_resource is not None: 2bbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c%c=c?c@c[c]cVba b k s t c d e f ,bgdbd`cr .b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctc@ [ ] ^ _ `
381 return self._memory_resource.is_device_accessible 2bbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c%c=c?c@c[c]cVb,bgdbd`cr .b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpcqcrcsctc
382 _init_mem_attrs(self) 1abkstcdef@[]^_`
383 return self._mem_attrs.is_device_accessible 1abkstcdef@[]^_`
385 @property
386 def is_host_accessible(self) -> bool:
387 """Return True if this buffer can be accessed by the CPU, otherwise False."""
388 if self._memory_resource is not None: 2bbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c%c=c?c@c[c]cVba b k s t c d e f ab{ | WbX + , - Y Z 0 1 2 3 . / 4 5 6 7 } : ; Ebu 8 9 ! v w x y z A # $ B C D E ~ = ? HbF % ' ( G H I J K L ) * M N O P ,bgdbd`cr
389 return self._memory_resource.is_host_accessible 2bbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c%c=c?c@c[c]cVbab{ | WbX + , - Y Z 0 1 2 3 . / 4 5 6 7 } : ; Ebu 8 9 ! v w x y z A # $ B C D E ~ = ? HbF % ' ( G H I J K L ) * M N O P ,bgdbd`cr
390 _init_mem_attrs(self) 1abkstcdef
391 return self._mem_attrs.is_host_accessible 1abkstcdef
393 @property
394 def is_mapped(self) -> bool:
395 """Return True if this buffer is mapped into the process via IPC."""
396 return getattr(self._ipc_data, "is_mapped", False) 2KbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSd,bhd
399 @property
400 def memory_resource(self) -> MemoryResource:
401 """Return the memory resource associated with this buffer."""
402 return self._memory_resource 2g h i j Q R S T U V W (d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o ;c,bvcgdwcqdbdxc`csd7c8c.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cqcrc_csctc@ [ ] ^ _ `
404 @property
405 def size(self) -> int:
406 """Return the memory size of this buffer."""
407 return self._size 2bbcbdbg h i j Q R S T U V W ;d=d?debfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBb(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o #c$c/d,d:d|c}c~cyczcAcBcCcDcEcFcGcHcIcJcKcLcMcNcOcPcQcRcScTcUcVcWcXcYcZc0c1c2c3c%cVb,bEdFdvcgdwc_d`d{dbdxc`c7c8cuc9cr !c.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cqcrc_csctc
409 @property
410 def owner(self) -> object:
411 """Return the object holding external allocation."""
412 return self._owner
415# Memory Attribute Query Helpers
416# ------------------------------
417cdef inline void _init_mem_attrs(Buffer self):
418 """Initialize memory attributes by querying the pointer."""
419 if not self._mem_attrs_inited: 1abkstcdef@[]^_`
420 _query_memory_attrs(self._mem_attrs, as_cu(self._h_ptr)) 1abkstcdef@[]^_`
421 self._mem_attrs_inited = True 1abkstcdef@[]^_`
424cdef inline int _query_memory_attrs(
425 _MemAttrs& out,
426 cydriver.CUdeviceptr ptr
427) except -1 nogil:
428 """Query memory attributes for a device pointer."""
429 cdef unsigned int memory_type = 0 1abkstcdef@[]^_`
430 cdef int is_managed = 0 1abkstcdef@[]^_`
431 cdef int device_id = 0 1abkstcdef@[]^_`
432 cdef cydriver.CUpointer_attribute attrs[3]
433 cdef uintptr_t vals[3]
435 attrs[0] = cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_MEMORY_TYPE 1abkstcdef@[]^_`
436 attrs[1] = cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_IS_MANAGED 1abkstcdef@[]^_`
437 attrs[2] = cydriver.CUpointer_attribute.CU_POINTER_ATTRIBUTE_DEVICE_ORDINAL 1abkstcdef@[]^_`
438 vals[0] = <uintptr_t><void*>&memory_type 1abkstcdef@[]^_`
439 vals[1] = <uintptr_t><void*>&is_managed 1abkstcdef@[]^_`
440 vals[2] = <uintptr_t><void*>&device_id 1abkstcdef@[]^_`
442 cdef cydriver.CUresult ret
443 ret = cydriver.cuPointerGetAttributes(3, attrs, <void**>vals, ptr) 1abkstcdef@[]^_`
444 if ret == cydriver.CUresult.CUDA_ERROR_NOT_INITIALIZED: 1abkstcdef@[]^_`
445 with cython.gil:
446 # Device class handles the cuInit call internally
447 Device()
448 ret = cydriver.cuPointerGetAttributes(3, attrs, <void**>vals, ptr)
449 HANDLE_RETURN(ret) 1abkstcdef@[]^_`
451 if memory_type == 0: 1abkstcdef@[]^_`
452 # unregistered host pointer
453 out.is_host_accessible = True 1kef@[]^_`
454 out.is_device_accessible = False 1kef@[]^_`
455 out.device_id = -1 1kef@[]^_`
456 elif ( 1abstcdef
457 is_managed 1abstcdef
458 or memory_type == cydriver.CUmemorytype.CU_MEMORYTYPE_HOST 1abcdef
459 ):
460 # Managed memory or pinned host memory
461 out.is_host_accessible = True 1stcdef
462 out.is_device_accessible = True 1stcdef
463 out.device_id = device_id 1stcdef
464 elif memory_type == cydriver.CUmemorytype.CU_MEMORYTYPE_DEVICE: 1ab
465 out.is_host_accessible = False 1ab
466 out.is_device_accessible = True 1ab
467 out.device_id = device_id 1ab
468 else:
469 with cython.gil:
470 raise ValueError(f"Unsupported memory type: {memory_type}")
471 return 0 1abkstcdef@[]^_`
474cdef class MemoryResource:
475 """Abstract base class for memory resources that manage allocation and
476 deallocation of buffers.
478 Subclasses must implement methods for allocating and deallocation, as well
479 as properties associated with this memory resource from which all allocated
480 buffers will inherit. (Since all :class:`Buffer` instances allocated and
481 returned by the :meth:`allocate` method would hold a reference to self, the
482 buffer properties are retrieved simply by looking up the underlying memory
483 resource's respective property.)
484 """
486 def allocate(self, size_t size, stream: Stream | GraphBuilder | None = None) -> Buffer:
487 """Allocate a buffer of the requested size.
489 Parameters
490 ----------
491 size : int
492 The size of the buffer to allocate, in bytes.
493 stream : :obj:`~_stream.Stream` | :obj:`~_graph.GraphBuilder`, optional
494 The stream on which to perform the allocation asynchronously.
495 If None, it is up to each memory resource implementation to decide
496 and document the behavior.
498 Returns
499 -------
500 Buffer
501 The allocated buffer object, which can be used for device or host operations
502 depending on the resource's properties.
503 """
504 raise TypeError("MemoryResource.allocate must be implemented by subclasses.") 2,b
506 def deallocate(self, ptr: DevicePointerT, size_t size, stream: Stream | GraphBuilder | None = None):
507 """Deallocate a buffer previously allocated by this resource.
509 Parameters
510 ----------
511 ptr : :obj:`~_memory.DevicePointerT`
512 The pointer or handle to the buffer to deallocate.
513 size : int
514 The size of the buffer to deallocate, in bytes.
515 stream : :obj:`~_stream.Stream` | :obj:`~_graph.GraphBuilder`, optional
516 The stream on which to perform the deallocation asynchronously.
517 If None, it is up to each memory resource implementation to decide
518 and document the behavior.
519 """
520 raise TypeError("MemoryResource.deallocate must be implemented by subclasses.")
522 @property
523 def is_device_accessible(self) -> bool:
524 """Whether buffers allocated by this resource are device-accessible."""
525 raise TypeError("MemoryResource.is_device_accessible must be implemented by subclasses.")
527 @property
528 def is_host_accessible(self) -> bool:
529 """Whether buffers allocated by this resource are host-accessible."""
530 raise TypeError("MemoryResource.is_host_accessible must be implemented by subclasses.")
532 @property
533 def device_id(self) -> int:
534 """Device ID associated with this memory resource, or -1 if not applicable."""
535 raise TypeError("MemoryResource.device_id must be implemented by subclasses.")
538# Buffer Implementation Helpers
539# -----------------------------
540cdef inline Buffer Buffer_from_deviceptr_handle(
541 DevicePtrHandle h_ptr,
542 size_t size,
543 MemoryResource mr,
544 object ipc_descriptor = None
545):
546 """Create a Buffer from an existing DevicePtrHandle."""
547 cdef Buffer buf = Buffer.__new__(Buffer) 2VdWdXd|d}d~dg h i j Q R S T U V W ;d=d?dIdJdKd(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o #c$ca b EdFdvcgdwc_d`d{d2d3d4d5d6d7d8d9d!d#d$d%d'dqdbdxc`csdr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc
548 buf._h_ptr = h_ptr 2VdWdXd|d}d~dg h i j Q R S T U V W ;d=d?dIdJdKd(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o #c$ca b EdFdvcgdwc_d`d{d2d3d4d5d6d7d8d9d!d#d$d%d'dqdbdxc`csdr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc
549 buf._size = size 2VdWdXd|d}d~dg h i j Q R S T U V W ;d=d?dIdJdKd(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o #c$ca b EdFdvcgdwc_d`d{d2d3d4d5d6d7d8d9d!d#d$d%d'dqdbdxc`csdr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc
550 buf._memory_resource = mr 2VdWdXd|d}d~dg h i j Q R S T U V W ;d=d?dIdJdKd(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o #c$ca b EdFdvcgdwc_d`d{d2d3d4d5d6d7d8d9d!d#d$d%d'dqdbdxc`csdr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc
551 buf._ipc_data = IPCDataForBuffer(ipc_descriptor, True) if ipc_descriptor is not None else None 2VdWdXd|d}d~dg h i j Q R S T U V W ;d=d?dIdJdKd(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o #c$ca b EdFdvcgdwc_d`d{d2d3d4d5d6d7d8d9d!d#d$d%d'dqdbdxc`csdr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc
552 buf._owner = None 2VdWdXd|d}d~dg h i j Q R S T U V W ;d=d?dIdJdKd(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o #c$ca b EdFdvcgdwc_d`d{d2d3d4d5d6d7d8d9d!d#d$d%d'dqdbdxc`csdr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc
553 buf._mem_attrs_inited = False 2VdWdXd|d}d~dg h i j Q R S T U V W ;d=d?dIdJdKd(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o #c$ca b EdFdvcgdwc_d`d{d2d3d4d5d6d7d8d9d!d#d$d%d'dqdbdxc`csdr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc
554 return buf 2VdWdXd|d}d~dg h i j Q R S T U V W ;d=d?dIdJdKd(d)d*d+d-d.dKbLbYdZdLdMd0d1dNdOdMbNbObPbQbRbSbTbPdQdRdSdl m p q n o #c$ca b EdFdvcgdwc_d`d{d2d3d4d5d6d7d8d9d!d#d$d%d'dqdbdxc`csdr {c!ctdudvdwdxdydzdAdBdjdkdldmdndodpdhdidCdDdcdddGdHd.b/b:b;b=b?b@b[b]b^b_b`b{b|b}b~bacbcccdcecfcgchcicjckclcmcncocpc^cedfdqcrc_csctc
557cdef inline void Buffer_close(Buffer self, object stream):
558 """Close a buffer, freeing its memory."""
559 cdef Stream s
560 if not self._h_ptr: 2bbcbdbVdWdXdg h i j Q R S T U V W IdJdKdebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbl m p q n o ;c-b$ba b k c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bEdFdvcgdwc2d3d4d5d6d7d8d9d!d#d$d%d'dqdad:crdbdxc`csd7c8cuc9c
561 return
562 # Update deallocation stream if provided
563 if stream is not None: 2bbcbdbVdWdXdg h i j Q R S T U V W IdJdKdebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbl m p q n o ;c-b$ba b k c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bEdFdvcgdwc2d3d4d5d6d7d8d9d!d#d$d%d'dqdad:crdbdxc`csd7c8cuc9c
564 s = Stream_accept(stream) 2IdJdKdvcwc:cxc
565 set_deallocation_stream(self._h_ptr, s._h_stream) 2IdJdKdvcwc:cxc
566 # Reset handle - RAII deleter will free the memory (and release owner ref in C++)
567 self._h_ptr.reset() 2bbcbdbVdWdXdg h i j Q R S T U V W IdJdKdebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbl m p q n o ;c-b$ba b k c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bEdFdvcgdwc2d3d4d5d6d7d8d9d!d#d$d%d'dqdad:crdbdxc`csd7c8cuc9c
568 self._size = 0 2bbcbdbVdWdXdg h i j Q R S T U V W IdJdKdebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbl m p q n o ;c-b$ba b k c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bEdFdvcgdwc2d3d4d5d6d7d8d9d!d#d$d%d'dqdad:crdbdxc`csd7c8cuc9c
569 self._memory_resource = None 2bbcbdbVdWdXdg h i j Q R S T U V W IdJdKdebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbl m p q n o ;c-b$ba b k c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bEdFdvcgdwc2d3d4d5d6d7d8d9d!d#d$d%d'dqdad:crdbdxc`csd7c8cuc9c
570 self._ipc_data = None 2bbcbdbVdWdXdg h i j Q R S T U V W IdJdKdebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbl m p q n o ;c-b$ba b k c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bEdFdvcgdwc2d3d4d5d6d7d8d9d!d#d$d%d'dqdad:crdbdxc`csd7c8cuc9c
571 self._owner = None 2bbcbdbVdWdXdg h i j Q R S T U V W IdJdKdebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzbAbBbl m p q n o ;c-b$ba b k c d e f 4c%bab6b{ 'b7b| Wb'c(c)cX Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb5c(b} 8b: )b9b; Eb*c+c,cu 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b6c*b~ !b= +b#b? Hb-c.c/cF 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b,bEdFdvcgdwc2d3d4d5d6d7d8d9d!d#d$d%d'dqdad:crdbdxc`csd7c8cuc9c
574cdef inline int Buffer_fill_uint8(Buffer self, uint8_t value, StreamHandle h_stream) except? -1:
575 cdef cydriver.CUdeviceptr ptr = as_cu(self._h_ptr) 2g h i j WbEbHb
576 cdef cydriver.CUstream s = as_cu(h_stream) 2g h i j WbEbHb
577 with nogil: 2g h i j WbEbHb
578 HANDLE_RETURN(cydriver.cuMemsetD8Async(ptr, value, self._size, s)) 2g h i j WbEbHb
579 return 0 2g h i j WbEbHb
582cdef inline int Buffer_fill_from_ptr(
583 Buffer self, const char* ptr, size_t width, StreamHandle h_stream
584) except? -1:
585 cdef size_t buffer_size = self._size 2%bab6b{ 'b7b| X Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb(b} 8b: )b9b; u 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b*b~ !b= +b#b? F 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b
586 cdef cydriver.CUdeviceptr dst = as_cu(self._h_ptr) 2%bab6b{ 'b7b| X Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb(b} 8b: )b9b; u 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b*b~ !b= +b#b? F 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b
587 cdef cydriver.CUstream s = as_cu(h_stream) 2%bab6b{ 'b7b| X Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb(b} 8b: )b9b; u 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b*b~ !b= +b#b? F 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b
589 if width == 1: 2%bab6b{ 'b7b| X Xb+ , - Y Z 0 1 2 3 Yb. / 4 5 Cb6 7 DbZb(b} 8b: )b9b; u 0b8 9 ! v w x y z A 1b# $ B C FbD E Gb2b*b~ !b= +b#b? F 3b% ' ( G H I J K L 4b) * M N IbO P Jb5b
590 with nogil: 2ab+ , - . / } 8 9 ! # $ ~ % ' ( ) *
591 HANDLE_RETURN(cydriver.cuMemsetD8Async(dst, (<uint8_t*>ptr)[0], buffer_size, s)) 2ab+ , - . / } 8 9 ! # $ ~ % ' ( ) *
592 elif width == 2:
593 if buffer_size & 0x1: 26b{ Y Z 0 4 5 Cb8b: v w x B C Fb!b= G H I M N Ib
594 raise ValueError(f"buffer size ({buffer_size}) must be divisible by 2") 26bCb8bFb!bIb
595 with nogil: 1{YZ045:vwxBC=GHIMN
596 HANDLE_RETURN(cydriver.cuMemsetD16Async(dst, (<uint16_t*>ptr)[0], buffer_size // 2, s)) 1{YZ045:vwxBC=GHIMN
597 elif width == 4:
598 if buffer_size & 0x3: 27b| X 1 2 3 6 7 Db9b; u y z A D E Gb#b? F J K L O P Jb
599 raise ValueError(f"buffer size ({buffer_size}) must be divisible by 4") 27bDb9bGb#bJb
600 with nogil: 1|X12367;uyzADE?FJKLOP
601 HANDLE_RETURN(cydriver.cuMemsetD32Async(dst, (<uint32_t*>ptr)[0], buffer_size // 4, s)) 1|X12367;uyzADE?FJKLOP
602 else:
603 raise ValueError(f"value must be 1, 2, or 4 bytes, got {width}") 2%b'bXbYbZb(b)b0b1b2b*b+b3b4b5b
604 return 0 2ab{ | X + , - Y Z 0 1 2 3 . / 4 5 6 7 } : ; u 8 9 ! v w x y z A # $ B C D E ~ = ? F % ' ( G H I J K L ) * M N O P