Coverage for cuda/core/graph/_subclasses.pyx: 94.24%
729 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-10 02:27 +0000
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-10 02:27 +0000
1# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2#
3# SPDX-License-Identifier: Apache-2.0
5"""GraphNode subclasses — EmptyNode through SwitchNode."""
7from __future__ import annotations
9from libc.stddef cimport size_t
10from libc.stdint cimport uintptr_t
11from libc.string cimport memset as c_memset
13from cuda.bindings cimport cydriver
15from cuda.core._event cimport Event, Event_check_open
16from cuda.core._kernel_arg_handler cimport ParamHolder
17from cuda.core._launch_config cimport LaunchConfig
18from cuda.core._memory._buffer cimport Buffer
19from cuda.core._module cimport Kernel
20from cuda.core.graph._graph_definition cimport (
21 GraphCondition,
22 GraphDefinition,
23 GD_check_valid,
24)
25from cuda.core.graph._graph_node cimport (
26 GraphNode,
27 GN_check_valid,
28 _get_memcpy_memory_type,
29 _init_memcpy_params,
30 _resolve_memcpy_operand,
31)
32from cuda.core._resource_handles cimport (
33 EventHandle,
34 GraphExecHandle,
35 GraphHandle,
36 GraphNodeHandle,
37 KernelHandle,
38 OpaqueHandle,
39 PreparedAttachment,
40 PreparedChildGraphUpdate,
41 PreparedExecAttachment,
42 as_cu,
43 as_intptr,
44 create_child_graph_handle,
45 create_event_handle_ref,
46 create_kernel_handle_ref,
47 graph_commit_attachment,
48 graph_commit_child_graph_update,
49 graph_commit_exec_attachment,
50 graph_get_attachment,
51 graph_node_get_graph,
52 graph_prepare_attachment,
53 graph_prepare_child_graph_update,
54 graph_prepare_exec_attachment,
55 make_opaque_py,
56)
57from cuda.core._utils.cuda_utils cimport HANDLE_RETURN, _parse_fill_value
58from cuda.core._utils.version cimport cy_binding_version, cy_driver_version
60from cuda.core.graph._host_callback cimport (
61 _is_py_host_trampoline,
62 _resolve_host_callback,
63)
65from cuda.core._utils.cuda_utils import driver, handle_return
66from cuda.core.typing import GraphConditionalType
68__all__ = [
69 'AllocNode',
70 'ChildGraphNode',
71 'ConditionalNode',
72 'EmptyNode',
73 'EventRecordNode',
74 'EventWaitNode',
75 'ExecutableChildGraphNode',
76 'ExecutableEventRecordNode',
77 'ExecutableEventWaitNode',
78 'ExecutableGraphNode',
79 'ExecutableHostCallbackNode',
80 'ExecutableKernelNode',
81 'ExecutableMemcpyNode',
82 'ExecutableMemsetNode',
83 'FreeNode',
84 'HostCallbackNode',
85 'IfElseNode',
86 'IfNode',
87 'KernelNode',
88 'MemcpyNode',
89 'MemsetNode',
90 'SwitchNode',
91 'WhileNode',
92]
95cdef bint _has_cuGraphNodeGetParams = False
96cdef bint _version_checked = False
99cdef void _require_graph_node_update_support() except *:
100 cdef tuple version = cy_driver_version() 1CELqW0O89mljcgdhiPZQRBJDMNvwxFGHyzS!*+KrefbATIa
101 if version < (12, 2, 0): 1CELqW0O89mljcgdhiPZQRBJDMNvwxFGHyzS!*+KrefbATIa
102 raise RuntimeError(
103 "Graph node mutation requires CUDA driver 12.2 or newer; "
104 f"using driver version {'.'.join(map(str, version))}"
105 )
106 version = cy_binding_version() 1CELqW0O89mljcgdhiPZQRBJDMNvwxFGHyzS!*+KrefbATIa
107 if version < (12, 2, 0): 1CELqW0O89mljcgdhiPZQRBJDMNvwxFGHyzS!*+KrefbATIa
108 raise RuntimeError(
109 "Graph node mutation requires cuda.bindings 12.2 or newer; "
110 f"using cuda.bindings version {'.'.join(map(str, version))}"
111 )
114cdef void _set_definition_node_params(
115 const GraphNodeHandle& h_node,
116 cydriver.CUgraphNodeParams* params,
117 OpaqueHandle owner0,
118 OpaqueHandle owner1=OpaqueHandle(),
119 cydriver.CUcontext update_ctx=NULL) except *:
120 cdef GraphHandle h_graph = graph_node_get_graph(h_node) 10O89mljcgdhiefba
121 cdef cydriver.CUgraphNode node = as_cu(h_node) 10O89mljcgdhiefba
122 if as_cu(h_graph) == NULL: 10O89mljcgdhiefba
123 raise RuntimeError("GraphDefinition is no longer valid")
124 if node == NULL: 10O89mljcgdhiefba
125 raise RuntimeError("GraphNode has been destroyed")
126 _require_graph_node_update_support() 10O89mljcgdhiefba
127 cdef cydriver.CUcontext previous_ctx = NULL 10O89mljcgdhiefba
128 cdef bint restore_ctx = False 10O89mljcgdhiefba
129 cdef PreparedAttachment prepared
131 HANDLE_RETURN(graph_prepare_attachment( 10O89mljcgdhiefba
132 h_graph, owner0, owner1, &prepared))
133 if update_ctx != NULL: 1k0O89mljcgdhiefba
134 with nogil: 1cgdhiefba
135 HANDLE_RETURN(cydriver.cuCtxGetCurrent(&previous_ctx)) 1cgdhiefba
136 if previous_ctx != update_ctx: 1cgdhiefba
137 HANDLE_RETURN(cydriver.cuCtxSetCurrent(update_ctx)) 1a
138 restore_ctx = True 1a
139 try: 10O89mljcgdhiefba
140 with nogil: 10O89mljcgdhiefba
141 HANDLE_RETURN(cydriver.cuGraphNodeSetParams(node, params)) 10O89mljcgdhiefba
142 finally:
143 if restore_ctx: 10O89mljcgdhiefba
144 with nogil: 1a
145 HANDLE_RETURN(cydriver.cuCtxSetCurrent(previous_ctx)) 1a
146 HANDLE_RETURN(graph_commit_attachment(prepared, node)) 10O89mljcgdhiefba
149cdef void _set_executable_node_params(
150 const GraphExecHandle& h_exec,
151 const GraphNodeHandle& h_node,
152 cydriver.CUgraphNodeParams* params,
153 OpaqueHandle owner0=OpaqueHandle(),
154 OpaqueHandle owner1=OpaqueHandle()) except *:
155 _require_graph_node_update_support() 1LqPBJDMNvwxFGHyzSKrATI
157 cdef cydriver.CUgraphExec graph_exec = as_cu(h_exec) 1LqPBJDMNvwxFGHyzSKrATI
158 cdef cydriver.CUgraphNode node = as_cu(h_node) 1LqPBJDMNvwxFGHyzSKrATI
159 if graph_exec == NULL: 1LqPBJDMNvwxFGHyzSKrATI
160 raise RuntimeError("Graph has been closed")
161 if node == NULL: 1LqPBJDMNvwxFGHyzSKrATI
162 raise RuntimeError("GraphNode has been destroyed")
164 cdef PreparedExecAttachment prepared
165 HANDLE_RETURN(graph_prepare_exec_attachment( 1LqPBJDMNvwxFGHyzSKrATI
166 h_exec, owner0, owner1, &prepared))
168 cdef cydriver.CUresult status
169 with nogil: 1LqPBJDMNvwxFGHyzSKrATI
170 status = cydriver.cuGraphExecNodeSetParams( 1LqPBJDMNvwxFGHyzSKrATI
171 graph_exec, node, params)
172 if status == cydriver.CUDA_SUCCESS: 1LqPBJDMNvwxFGHyzSKrATI
173 graph_commit_exec_attachment(prepared) 1LqPBJDMNvwxFGHyzSKrTI
174 HANDLE_RETURN(status) 1LqPBJDMNvwxFGHyzSKrATI
177cdef bint _get_executable_node_enabled(
178 const GraphExecHandle& h_exec,
179 const GraphNodeHandle& h_node) except *:
180 _require_graph_node_update_support() 1ZQR
182 cdef cydriver.CUgraphExec graph_exec = as_cu(h_exec) 1ZQR
183 cdef cydriver.CUgraphNode node = as_cu(h_node) 1ZQR
184 cdef unsigned int enabled
185 if graph_exec == NULL: 1ZQR
186 raise RuntimeError("Graph has been closed")
187 if node == NULL: 1ZQR
188 raise RuntimeError("GraphNode has been destroyed")
189 with nogil: 1ZQR
190 HANDLE_RETURN(cydriver.cuGraphNodeGetEnabled( 1ZQR
191 graph_exec, node, &enabled))
192 return enabled != 0 1ZQR
195cdef void _set_executable_node_enabled(
196 const GraphExecHandle& h_exec,
197 const GraphNodeHandle& h_node,
198 bint enabled) except *:
199 _require_graph_node_update_support() 1ZQR
201 cdef cydriver.CUgraphExec graph_exec = as_cu(h_exec) 1ZQR
202 cdef cydriver.CUgraphNode node = as_cu(h_node) 1ZQR
203 if graph_exec == NULL: 1ZQR
204 raise RuntimeError("Graph has been closed")
205 if node == NULL: 1ZQR
206 raise RuntimeError("GraphNode has been destroyed")
207 with nogil: 1ZQR
208 HANDLE_RETURN(cydriver.cuGraphNodeSetEnabled( 1ZQR
209 graph_exec, node, <unsigned int>enabled))
212cdef bint _check_node_get_params():
213 global _has_cuGraphNodeGetParams, _version_checked
214 if not _version_checked: 1X13452Y6.cgdhistu#$nopUVef7ba
215 from cuda.core._utils.version import binding_version, driver_version 1XY
216 _has_cuGraphNodeGetParams = (
217 driver_version() >= (13, 2, 0) and binding_version() >= (13, 2, 0) 1XY
218 )
219 _version_checked = True 1XY
220 return _has_cuGraphNodeGetParams 1X13452Y6.cgdhistu#$nopUVef7ba
223cdef void _reject_unsupported_kernel_node(
224 cydriver.CUgraphNode node) except *:
225 cdef cydriver.CUkernelNodeAttrValue cluster
226 cdef cydriver.CUkernelNodeAttrValue cooperative
228 c_memset(&cluster, 0, sizeof(cluster)) 1mlj*+
229 c_memset(&cooperative, 0, sizeof(cooperative)) 1mlj*+
230 with nogil: 1mlj*+
231 HANDLE_RETURN(cydriver.cuGraphKernelNodeGetAttribute( 1mlj*+
232 node, <cydriver.CUkernelNodeAttrID>(
233 cydriver.CU_KERNEL_NODE_ATTRIBUTE_CLUSTER_DIMENSION),
234 &cluster))
235 HANDLE_RETURN(cydriver.cuGraphKernelNodeGetAttribute( 1mlj*+
236 node, <cydriver.CUkernelNodeAttrID>(
237 cydriver.CU_KERNEL_NODE_ATTRIBUTE_COOPERATIVE),
238 &cooperative))
239 if (cluster.clusterDim.x != 0 or cluster.clusterDim.y != 0 or 1mlj*+
240 cluster.clusterDim.z != 0 or cooperative.cooperative != 0): 1mlj*+
241 raise NotImplementedError(
242 "updating clustered or cooperative kernel nodes is not supported")
245cdef bint _is_supported_memcpy_descriptor(
246 cydriver.CUDA_MEMCPY3D* params) noexcept nogil:
247 return (
248 (params.srcMemoryType == cydriver.CU_MEMORYTYPE_HOST or 1cgdstunopef7a
249 params.srcMemoryType == cydriver.CU_MEMORYTYPE_DEVICE) 1cgdstunopef7a
250 and (params.dstMemoryType == cydriver.CU_MEMORYTYPE_HOST or 1cgdstunopef7a
251 params.dstMemoryType == cydriver.CU_MEMORYTYPE_DEVICE) 1cgdstunopef7a
252 and params.srcXInBytes == 0 1cgdstunopef7a
253 and params.srcY == 0 1cgdstunopefa
254 and params.srcZ == 0 1cgdstunopefa
255 and params.srcLOD == 0 1cgdstunopefa
256 and params.srcPitch == 0 1cgdstunopefa
257 and params.srcHeight == 0 1cgdstunopefa
258 and params.dstXInBytes == 0 1cgdstunopefa
259 and params.dstY == 0 1cgdstunopefa
260 and params.dstZ == 0 1cgdstunopefa
261 and params.dstLOD == 0 1cgdstunopefa
262 and params.dstPitch == 0 1cgdstunopefa
263 and params.dstHeight == 0 1cgdstunopefa
264 and params.Height == 1 1cgdstunopefa
265 and params.Depth == 1 1cgdstunopefa
266 and params.reserved0 == NULL 1cgdstunopefa
267 and params.reserved1 == NULL 1cgdstunopefa
268 )
271cdef class EmptyNode(GraphNode):
272 """An empty (synchronization) node."""
274 @staticmethod
275 cdef EmptyNode _create_impl(GraphNodeHandle h_node):
276 cdef EmptyNode n = EmptyNode.__new__(EmptyNode) 2gkhk0e1eik% ' ( ) 2e3e4ejkkklk5eLb6ebbMb7e8e9e!e#eNb$eHbOb%emkPb'eQb(e)e*e+enk,e-eok.e|f}f~fagbgpkjjqkrkskcgtkukdcK ogpg/eRbkj:eSbTb;eUb=eVb?eWb@eXb[eubGdHdCdsd]e^epcYbIb_e`e{eZbcb|e0b}e1b] ~e2b, dbeb_ 3b4b5b6b/ af7bbf8bcf9bdf!b#bef$bff%bgf'bhf(bifvbIdJdDdtdjfkfqc)bJblfmfnf*bfbof+bpf,b^ qf-b- gbhb` .b/b:b;b: rf=bsf?btf@buf[bvf]bwf^bxf_byf`bzf{bAf|bBf}b
277 n._h_node = h_node 2gkhk0e1eik% ' ( ) 2e3e4ejkkklk5eLb6ebbMb7e8e9e!e#eNb$eHbOb%emkPb'eQb(e)e*e+enk,e-eok.e|f}f~fagbgpkjjqkrkskcgtkukdcK ogpg/eRbkj:eSbTb;eUb=eVb?eWb@eXb[eubGdHdCdsd]e^epcYbIb_e`e{eZbcb|e0b}e1b] ~e2b, dbeb_ 3b4b5b6b/ af7bbf8bcf9bdf!b#bef$bff%bgf'bhf(bifvbIdJdDdtdjfkfqc)bJblfmfnf*bfbof+bpf,b^ qf-b- gbhb` .b/b:b;b: rf=bsf?btf@buf[bvf]bwf^bxf_byf`bzf{bAf|bBf}b
278 return n 2gkhk0e1eik% ' ( ) 2e3e4ejkkklk5eLb6ebbMb7e8e9e!e#eNb$eHbOb%emkPb'eQb(e)e*e+enk,e-eok.e|f}f~fagbgpkjjqkrkskcgtkukdcK ogpg/eRbkj:eSbTb;eUb=eVb?eWb@eXb[eubGdHdCdsd]e^epcYbIb_e`e{eZbcb|e0b}e1b] ~e2b, dbeb_ 3b4b5b6b/ af7bbf8bcf9bdf!b#bef$bff%bgf'bhf(bifvbIdJdDdtdjfkfqc)bJblfmfnf*bfbof+bpf,b^ qf-b- gbhb` .b/b:b;b: rf=bsf?btf@buf[bvf]bwf^bxf_byf`bzf{bAf|bBf}b
280 def __repr__(self) -> str:
281 return f"<EmptyNode handle=0x{as_intptr(self._h_node):x}>" 2jjkjHk
284cdef class KernelNode(GraphNode):
285 """A kernel launch node.
287 Properties
288 ----------
289 grid : tuple of int
290 Grid dimensions (gridDimX, gridDimY, gridDimZ).
291 block : tuple of int
292 Block dimensions (blockDimX, blockDimY, blockDimZ).
293 shmem_size : int
294 Dynamic shared memory size in bytes.
295 kernel : Kernel
296 The kernel object for this launch node.
297 config : LaunchConfig
298 A LaunchConfig reconstructed from this node's parameters.
299 """
301 @staticmethod
302 cdef KernelNode _create_with_params(GraphNodeHandle h_node,
303 tuple grid, tuple block, unsigned int shmem_size,
304 KernelHandle h_kernel):
305 """Create from known params (called by launch() builder)."""
306 cdef KernelNode n = KernelNode.__new__(KernelNode) 20dMh1d2d3dCfNhOhPhQhRhShThKdDfLdEfMdFfNdGfOdHfPdIfQdUhRdEdSdTdecVhWhygHeXhYh{ |f}f~fagbg? q m l j Zh0h1hzgAgBg~bacZ rcv w x dc* dg+ r FdA 2hJf3hKf4hfcUdLf5hVdWdudMfNfOfPfQf6hRf7hSf8hubpcTf9hibUf!hVf#hWfXfYfbc!d$h%h] ~ 'h(hZf)h, ; 0f*h1f+h2f,h3f-hgcXd4f.hYdZdvd5f6f7f8f9f/h!f:h#f;hvbqc$f=hjb%f?h'f@h(f)f*fcc#d[h]h^ ab^h_h+f`h- = ,f{h-f|h.f}h/f~h:fai;fbi=fci?fdi@fei[ffi]fgi
307 n._h_node = h_node 20dMh1d2d3dCfNhOhPhQhRhShThKdDfLdEfMdFfNdGfOdHfPdIfQdUhRdEdSdTdecVhWhygHeXhYh{ |f}f~fagbg? q m l j Zh0h1hzgAgBg~bacZ rcv w x dc* dg+ r FdA 2hJf3hKf4hfcUdLf5hVdWdudMfNfOfPfQf6hRf7hSf8hubpcTf9hibUf!hVf#hWfXfYfbc!d$h%h] ~ 'h(hZf)h, ; 0f*h1f+h2f,h3f-hgcXd4f.hYdZdvd5f6f7f8f9f/h!f:h#f;hvbqc$f=hjb%f?h'f@h(f)f*fcc#d[h]h^ ab^h_h+f`h- = ,f{h-f|h.f}h/f~h:fai;fbi=fci?fdi@fei[ffi]fgi
308 n._grid = grid 20dMh1d2d3dCfNhOhPhQhRhShThKdDfLdEfMdFfNdGfOdHfPdIfQdUhRdEdSdTdecVhWhygHeXhYh{ |f}f~fagbg? q m l j Zh0h1hzgAgBg~bacZ rcv w x dc* dg+ r FdA 2hJf3hKf4hfcUdLf5hVdWdudMfNfOfPfQf6hRf7hSf8hubpcTf9hibUf!hVf#hWfXfYfbc!d$h%h] ~ 'h(hZf)h, ; 0f*h1f+h2f,h3f-hgcXd4f.hYdZdvd5f6f7f8f9f/h!f:h#f;hvbqc$f=hjb%f?h'f@h(f)f*fcc#d[h]h^ ab^h_h+f`h- = ,f{h-f|h.f}h/f~h:fai;fbi=fci?fdi@fei[ffi]fgi
309 n._block = block 20dMh1d2d3dCfNhOhPhQhRhShThKdDfLdEfMdFfNdGfOdHfPdIfQdUhRdEdSdTdecVhWhygHeXhYh{ |f}f~fagbg? q m l j Zh0h1hzgAgBg~bacZ rcv w x dc* dg+ r FdA 2hJf3hKf4hfcUdLf5hVdWdudMfNfOfPfQf6hRf7hSf8hubpcTf9hibUf!hVf#hWfXfYfbc!d$h%h] ~ 'h(hZf)h, ; 0f*h1f+h2f,h3f-hgcXd4f.hYdZdvd5f6f7f8f9f/h!f:h#f;hvbqc$f=hjb%f?h'f@h(f)f*fcc#d[h]h^ ab^h_h+f`h- = ,f{h-f|h.f}h/f~h:fai;fbi=fci?fdi@fei[ffi]fgi
310 n._shmem_size = shmem_size 20dMh1d2d3dCfNhOhPhQhRhShThKdDfLdEfMdFfNdGfOdHfPdIfQdUhRdEdSdTdecVhWhygHeXhYh{ |f}f~fagbg? q m l j Zh0h1hzgAgBg~bacZ rcv w x dc* dg+ r FdA 2hJf3hKf4hfcUdLf5hVdWdudMfNfOfPfQf6hRf7hSf8hubpcTf9hibUf!hVf#hWfXfYfbc!d$h%h] ~ 'h(hZf)h, ; 0f*h1f+h2f,h3f-hgcXd4f.hYdZdvd5f6f7f8f9f/h!f:h#f;hvbqc$f=hjb%f?h'f@h(f)f*fcc#d[h]h^ ab^h_h+f`h- = ,f{h-f|h.f}h/f~h:fai;fbi=fci?fdi@fei[ffi]fgi
311 n._h_kernel = h_kernel 20dMh1d2d3dCfNhOhPhQhRhShThKdDfLdEfMdFfNdGfOdHfPdIfQdUhRdEdSdTdecVhWhygHeXhYh{ |f}f~fagbg? q m l j Zh0h1hzgAgBg~bacZ rcv w x dc* dg+ r FdA 2hJf3hKf4hfcUdLf5hVdWdudMfNfOfPfQf6hRf7hSf8hubpcTf9hibUf!hVf#hWfXfYfbc!d$h%h] ~ 'h(hZf)h, ; 0f*h1f+h2f,h3f-hgcXd4f.hYdZdvd5f6f7f8f9f/h!f:h#f;hvbqc$f=hjb%f?h'f@h(f)f*fcc#d[h]h^ ab^h_h+f`h- = ,f{h-f|h.f}h/f~h:fai;fbi=fci?fdi@fei[ffi]fgi
312 return n 20dMh1d2d3dCfNhOhPhQhRhShThKdDfLdEfMdFfNdGfOdHfPdIfQdUhRdEdSdTdecVhWhygHeXhYh{ |f}f~fagbg? q m l j Zh0h1hzgAgBg~bacZ rcv w x dc* dg+ r FdA 2hJf3hKf4hfcUdLf5hVdWdudMfNfOfPfQf6hRf7hSf8hubpcTf9hibUf!hVf#hWfXfYfbc!d$h%h] ~ 'h(hZf)h, ; 0f*h1f+h2f,h3f-hgcXd4f.hYdZdvd5f6f7f8f9f/h!f:h#f;hvbqc$f=hjb%f?h'f@h(f)f*fcc#d[h]h^ ab^h_h+f`h- = ,f{h-f|h.f}h/f~h:fai;fbi=fci?fdi@fei[ffi]fgi
314 @staticmethod
315 cdef KernelNode _create_from_driver(GraphNodeHandle h_node):
316 """Create by fetching params from the driver (called by _create factory)."""
317 cdef cydriver.CUgraphNode node = as_cu(h_node) 20d1d2d3dKdRdEdSdTdec{ ?
318 cdef cydriver.CUDA_KERNEL_NODE_PARAMS params
319 with nogil: 20d1d2d3dKdRdEdSdTdec{ ?
320 HANDLE_RETURN(cydriver.cuGraphKernelNodeGetParams(node, ¶ms)) 20d1d2d3dKdRdEdSdTdec{ ?
321 cdef KernelHandle h_kernel = create_kernel_handle_ref(params.kern) 20d1d2d3dKdRdEdSdTdec{ ?
322 return KernelNode._create_with_params( 20d1d2d3dKdRdEdSdTdec{ ?
323 h_node,
324 (params.gridDimX, params.gridDimY, params.gridDimZ), 20d1d2d3dKdRdEdSdTdec{ ?
325 (params.blockDimX, params.blockDimY, params.blockDimZ), 20d1d2d3dKdRdEdSdTdec{ ?
326 params.sharedMemBytes,
327 h_kernel)
329 def __repr__(self) -> str:
330 return (f"<KernelNode handle=0x{as_intptr(self._h_node):x}" 2q r wk
331 f" kernel=0x{as_intptr(self._h_kernel):x}>") 2q r wk
333 def update(
334 self,
335 *,
336 config: LaunchConfig | None = None,
337 kernel: Kernel | None = None,
338 args=None,
339 ) -> None:
340 """Replace selected kernel launch parameters.
342 Omitted parameters preserve their current values. Changing ``kernel``
343 requires ``args``, including ``args=()`` for a no-argument kernel.
344 Clustered and cooperative kernel nodes are not supported.
346 .. warning::
348 Use caution when a retained kernel argument directly or indirectly
349 owns a graph. Any reference cycle involving the argument and a
350 graph that retains it cannot be broken by Python's cyclic garbage
351 collector. Use a weak reference to break such cycles.
352 """
353 GN_check_valid(self) 2m l j zgAgBg* + Fd
354 cdef LaunchConfig c_config
355 cdef Kernel c_kernel
356 cdef ParamHolder arg_holder
357 cdef object kernel_args
358 cdef KernelHandle h_kernel = self._h_kernel 2m l j * + Fd
359 cdef OpaqueHandle kernel_owner
360 cdef OpaqueHandle args_owner
361 cdef GraphHandle h_graph = graph_node_get_graph(self._h_node) 2m l j * + Fd
362 cdef cydriver.CUgraphNode node = as_cu(self._h_node) 2m l j * + Fd
363 cdef cydriver.CUgraphNodeParams params
365 if config is not None: 2m l j * + Fd
366 c_config = config 2l Fd
367 if (c_config.cluster is not None or 2l Fd
368 c_config.is_cooperative): 2l Fd
369 raise NotImplementedError( 2Fd
370 "updating clustered or cooperative kernel nodes is not "
371 "supported")
372 _require_graph_node_update_support() 1mlj*+
373 _reject_unsupported_kernel_node(node) 1mlj*+
374 if kernel is not None: 1mlj*+
375 if args is None: 1j+
376 raise ValueError("changing kernel requires args") 1+
377 c_kernel = kernel 1j
378 h_kernel = c_kernel._h_kernel 1j
379 if args is not None: 1mlj*
380 arg_holder = ParamHolder(args) 1mj*
382 c_memset(¶ms, 0, sizeof(params)) 1mlj
383 params.type = cydriver.CU_GRAPH_NODE_TYPE_KERNEL 1mlj
384 with nogil: 1mlj
385 HANDLE_RETURN(cydriver.cuGraphKernelNodeGetParams( 1mlj
386 node, <cydriver.CUDA_KERNEL_NODE_PARAMS*>¶ms.kernel))
387 HANDLE_RETURN(graph_get_attachment( 1mlj
388 h_graph, node, &kernel_owner, &args_owner))
390 if config is not None: 1mlj
391 params.kernel.gridDimX = c_config.grid[0] 1l
392 params.kernel.gridDimY = c_config.grid[1] 1l
393 params.kernel.gridDimZ = c_config.grid[2] 1l
394 params.kernel.blockDimX = c_config.block[0] 1l
395 params.kernel.blockDimY = c_config.block[1] 1l
396 params.kernel.blockDimZ = c_config.block[2] 1l
397 params.kernel.sharedMemBytes = c_config.shmem_size 1l
398 if kernel is not None: 1mlj
399 params.kernel.kern = as_cu(h_kernel) 1j
400 params.kernel.func = <cydriver.CUfunction>NULL 1j
401 params.kernel.ctx = <cydriver.CUcontext>NULL 1j
402 kernel_owner = h_kernel 1j
403 if args is not None: 1mlj
404 params.kernel.kernelParams = <void**><uintptr_t>arg_holder.ptr 1mj
405 params.kernel.extra = NULL 1mj
406 kernel_args = arg_holder.kernel_args 1mj
407 if kernel_args is None: 1mj
408 args_owner = OpaqueHandle() 1j
409 else:
410 args_owner = make_opaque_py(kernel_args) 1m
412 _set_definition_node_params( 1mlj
413 self._h_node, ¶ms, kernel_owner, args_owner)
414 self._grid = ( 1mlj
415 params.kernel.gridDimX, 1mlj
416 params.kernel.gridDimY, 1mlj
417 params.kernel.gridDimZ, 1mlj
418 )
419 self._block = ( 1mlj
420 params.kernel.blockDimX, 1mlj
421 params.kernel.blockDimY, 1mlj
422 params.kernel.blockDimZ, 1mlj
423 )
424 self._shmem_size = params.kernel.sharedMemBytes 1mlj
425 self._h_kernel = h_kernel 1mlj
427 @property
428 def grid(self) -> tuple[int, int, int]:
429 """Grid dimensions as a 3-tuple (gridDimX, gridDimY, gridDimZ)."""
430 return self._grid 2likb
432 @property
433 def block(self) -> tuple[int, int, int]:
434 """Block dimensions as a 3-tuple (blockDimX, blockDimY, blockDimZ)."""
435 return self._block 2likb
437 @property
438 def shmem_size(self) -> int:
439 """Dynamic shared memory size in bytes."""
440 return self._shmem_size 2likb
442 @property
443 def kernel(self) -> Kernel:
444 """The Kernel object for this launch node."""
445 return Kernel._from_handle(self._h_kernel) 2likbygHem l j v w x * dg+
447 @property
448 def config(self) -> LaunchConfig:
449 """A LaunchConfig reconstructed from this node's grid, block, and shmem_size.
451 Note: cluster dimensions and is_cooperative are not preserved
452 by the CUDA driver's kernel node params, so they are not included.
453 """
454 return LaunchConfig(grid=self._grid, block=self._block, 2likbm l j v w x * dg+
455 shmem_size=self._shmem_size) 2likbm l j v w x * dg+
458cdef class AllocNode(GraphNode):
459 """A memory allocation node.
461 Properties
462 ----------
463 dptr : int
464 The device pointer for the allocation.
465 bytesize : int
466 The number of bytes allocated.
467 device_id : int
468 The device on which the allocation was made.
469 memory_type : GraphMemoryType | str
470 The type of memory allocated.
471 peer_access : tuple of int
472 Device IDs that have read-write access to this allocation.
473 """
475 @staticmethod
476 cdef AllocNode _create_with_params(GraphNodeHandle h_node,
477 cydriver.CUdeviceptr dptr, size_t bytesize,
478 int device_id, str memory_type, tuple peer_access):
479 """Create from known params (called by allocate() builder)."""
480 cdef AllocNode n = AllocNode.__new__(AllocNode) 2qgrg$dCgDgEgFg0eGg1eHgIg%d'd(d)d*d% ' ( ) wbxbybzbJgKgLg2e3e4eMgNg5eIeJe+dLdLbsctcucvcsbOgtbPg6ehcKeicLejc,dkbMdbbMblbwcmbxcnbycobzcQg7eRg8eSgTgUg9eVg!eWgXgYgZg#eMeNe-dNdNbAcBcCcDcEc0gFc1gGc$eHcOeIcPeJc.dKcOdHbObLcMcNcOcPcQcRcScTc2gUc3gVc%eWcQeXcReYc/dZcPdPb0c1c2c3c4c5c6c7c4g5g'eSeTe:dQdQb8c9c!c#c6g(e7g)e8g9g!g*e#g+e$g%g'g,e(g-e)g*g.esg+g;d=dAb4d,g/e?dRb$c-g:e@dSb%cfcUeVe[d5d.g/gUdTb'c:g;g=g;e]dUb(c?g=e^dVb)c@g?e_dWb*c[g@e`dXb+c[eubGdHdCdsd]e^epcYbIb_e`e]g{e{dZb,cibwdxdkc|d}dcbBb~dae^g|ebe0b-c_g}ece1b.cbc] ~ `g~ede2b/c, dbeb_ 3b4b5b6b; CbDbpb:c;c/ =c?c{gafee7b@c|gbffe8b[c}gcfge9b]c~gdfhe!b^cgcWeXeie6dahbhXd#b_cchdhehefje$b`cfhffke%b{cghgfle'b|chhhfme(b}cifvbIdJdDdtdjfkfqc)bJblfmfihnfne*b~cjbydzdlcoepefbEbqerejhofse+badkhpfte,bbdcc^ ablhqfue-bcd- gbhb` .b/b:b;b= FbGbqbdded: fdgdmhrfve=bhdnhsfwe?bidohtfxe@bjdphufye[bkdqhvfze]bldrhwfAe^bmdshxfBe_bndthyfCe`boduhzfDe{bpdvhAfEe|bqdwhBfFe}brd
481 n._h_node = h_node 2qgrg$dCgDgEgFg0eGg1eHgIg%d'd(d)d*d% ' ( ) wbxbybzbJgKgLg2e3e4eMgNg5eIeJe+dLdLbsctcucvcsbOgtbPg6ehcKeicLejc,dkbMdbbMblbwcmbxcnbycobzcQg7eRg8eSgTgUg9eVg!eWgXgYgZg#eMeNe-dNdNbAcBcCcDcEc0gFc1gGc$eHcOeIcPeJc.dKcOdHbObLcMcNcOcPcQcRcScTc2gUc3gVc%eWcQeXcReYc/dZcPdPb0c1c2c3c4c5c6c7c4g5g'eSeTe:dQdQb8c9c!c#c6g(e7g)e8g9g!g*e#g+e$g%g'g,e(g-e)g*g.esg+g;d=dAb4d,g/e?dRb$c-g:e@dSb%cfcUeVe[d5d.g/gUdTb'c:g;g=g;e]dUb(c?g=e^dVb)c@g?e_dWb*c[g@e`dXb+c[eubGdHdCdsd]e^epcYbIb_e`e]g{e{dZb,cibwdxdkc|d}dcbBb~dae^g|ebe0b-c_g}ece1b.cbc] ~ `g~ede2b/c, dbeb_ 3b4b5b6b; CbDbpb:c;c/ =c?c{gafee7b@c|gbffe8b[c}gcfge9b]c~gdfhe!b^cgcWeXeie6dahbhXd#b_cchdhehefje$b`cfhffke%b{cghgfle'b|chhhfme(b}cifvbIdJdDdtdjfkfqc)bJblfmfihnfne*b~cjbydzdlcoepefbEbqerejhofse+badkhpfte,bbdcc^ ablhqfue-bcd- gbhb` .b/b:b;b= FbGbqbdded: fdgdmhrfve=bhdnhsfwe?bidohtfxe@bjdphufye[bkdqhvfze]bldrhwfAe^bmdshxfBe_bndthyfCe`boduhzfDe{bpdvhAfEe|bqdwhBfFe}brd
482 n._dptr = dptr 2qgrg$dCgDgEgFg0eGg1eHgIg%d'd(d)d*d% ' ( ) wbxbybzbJgKgLg2e3e4eMgNg5eIeJe+dLdLbsctcucvcsbOgtbPg6ehcKeicLejc,dkbMdbbMblbwcmbxcnbycobzcQg7eRg8eSgTgUg9eVg!eWgXgYgZg#eMeNe-dNdNbAcBcCcDcEc0gFc1gGc$eHcOeIcPeJc.dKcOdHbObLcMcNcOcPcQcRcScTc2gUc3gVc%eWcQeXcReYc/dZcPdPb0c1c2c3c4c5c6c7c4g5g'eSeTe:dQdQb8c9c!c#c6g(e7g)e8g9g!g*e#g+e$g%g'g,e(g-e)g*g.esg+g;d=dAb4d,g/e?dRb$c-g:e@dSb%cfcUeVe[d5d.g/gUdTb'c:g;g=g;e]dUb(c?g=e^dVb)c@g?e_dWb*c[g@e`dXb+c[eubGdHdCdsd]e^epcYbIb_e`e]g{e{dZb,cibwdxdkc|d}dcbBb~dae^g|ebe0b-c_g}ece1b.cbc] ~ `g~ede2b/c, dbeb_ 3b4b5b6b; CbDbpb:c;c/ =c?c{gafee7b@c|gbffe8b[c}gcfge9b]c~gdfhe!b^cgcWeXeie6dahbhXd#b_cchdhehefje$b`cfhffke%b{cghgfle'b|chhhfme(b}cifvbIdJdDdtdjfkfqc)bJblfmfihnfne*b~cjbydzdlcoepefbEbqerejhofse+badkhpfte,bbdcc^ ablhqfue-bcd- gbhb` .b/b:b;b= FbGbqbdded: fdgdmhrfve=bhdnhsfwe?bidohtfxe@bjdphufye[bkdqhvfze]bldrhwfAe^bmdshxfBe_bndthyfCe`boduhzfDe{bpdvhAfEe|bqdwhBfFe}brd
483 n._bytesize = bytesize 2qgrg$dCgDgEgFg0eGg1eHgIg%d'd(d)d*d% ' ( ) wbxbybzbJgKgLg2e3e4eMgNg5eIeJe+dLdLbsctcucvcsbOgtbPg6ehcKeicLejc,dkbMdbbMblbwcmbxcnbycobzcQg7eRg8eSgTgUg9eVg!eWgXgYgZg#eMeNe-dNdNbAcBcCcDcEc0gFc1gGc$eHcOeIcPeJc.dKcOdHbObLcMcNcOcPcQcRcScTc2gUc3gVc%eWcQeXcReYc/dZcPdPb0c1c2c3c4c5c6c7c4g5g'eSeTe:dQdQb8c9c!c#c6g(e7g)e8g9g!g*e#g+e$g%g'g,e(g-e)g*g.esg+g;d=dAb4d,g/e?dRb$c-g:e@dSb%cfcUeVe[d5d.g/gUdTb'c:g;g=g;e]dUb(c?g=e^dVb)c@g?e_dWb*c[g@e`dXb+c[eubGdHdCdsd]e^epcYbIb_e`e]g{e{dZb,cibwdxdkc|d}dcbBb~dae^g|ebe0b-c_g}ece1b.cbc] ~ `g~ede2b/c, dbeb_ 3b4b5b6b; CbDbpb:c;c/ =c?c{gafee7b@c|gbffe8b[c}gcfge9b]c~gdfhe!b^cgcWeXeie6dahbhXd#b_cchdhehefje$b`cfhffke%b{cghgfle'b|chhhfme(b}cifvbIdJdDdtdjfkfqc)bJblfmfihnfne*b~cjbydzdlcoepefbEbqerejhofse+badkhpfte,bbdcc^ ablhqfue-bcd- gbhb` .b/b:b;b= FbGbqbdded: fdgdmhrfve=bhdnhsfwe?bidohtfxe@bjdphufye[bkdqhvfze]bldrhwfAe^bmdshxfBe_bndthyfCe`boduhzfDe{bpdvhAfEe|bqdwhBfFe}brd
484 n._device_id = device_id 2qgrg$dCgDgEgFg0eGg1eHgIg%d'd(d)d*d% ' ( ) wbxbybzbJgKgLg2e3e4eMgNg5eIeJe+dLdLbsctcucvcsbOgtbPg6ehcKeicLejc,dkbMdbbMblbwcmbxcnbycobzcQg7eRg8eSgTgUg9eVg!eWgXgYgZg#eMeNe-dNdNbAcBcCcDcEc0gFc1gGc$eHcOeIcPeJc.dKcOdHbObLcMcNcOcPcQcRcScTc2gUc3gVc%eWcQeXcReYc/dZcPdPb0c1c2c3c4c5c6c7c4g5g'eSeTe:dQdQb8c9c!c#c6g(e7g)e8g9g!g*e#g+e$g%g'g,e(g-e)g*g.esg+g;d=dAb4d,g/e?dRb$c-g:e@dSb%cfcUeVe[d5d.g/gUdTb'c:g;g=g;e]dUb(c?g=e^dVb)c@g?e_dWb*c[g@e`dXb+c[eubGdHdCdsd]e^epcYbIb_e`e]g{e{dZb,cibwdxdkc|d}dcbBb~dae^g|ebe0b-c_g}ece1b.cbc] ~ `g~ede2b/c, dbeb_ 3b4b5b6b; CbDbpb:c;c/ =c?c{gafee7b@c|gbffe8b[c}gcfge9b]c~gdfhe!b^cgcWeXeie6dahbhXd#b_cchdhehefje$b`cfhffke%b{cghgfle'b|chhhfme(b}cifvbIdJdDdtdjfkfqc)bJblfmfihnfne*b~cjbydzdlcoepefbEbqerejhofse+badkhpfte,bbdcc^ ablhqfue-bcd- gbhb` .b/b:b;b= FbGbqbdded: fdgdmhrfve=bhdnhsfwe?bidohtfxe@bjdphufye[bkdqhvfze]bldrhwfAe^bmdshxfBe_bndthyfCe`boduhzfDe{bpdvhAfEe|bqdwhBfFe}brd
485 n._memory_type = memory_type 2qgrg$dCgDgEgFg0eGg1eHgIg%d'd(d)d*d% ' ( ) wbxbybzbJgKgLg2e3e4eMgNg5eIeJe+dLdLbsctcucvcsbOgtbPg6ehcKeicLejc,dkbMdbbMblbwcmbxcnbycobzcQg7eRg8eSgTgUg9eVg!eWgXgYgZg#eMeNe-dNdNbAcBcCcDcEc0gFc1gGc$eHcOeIcPeJc.dKcOdHbObLcMcNcOcPcQcRcScTc2gUc3gVc%eWcQeXcReYc/dZcPdPb0c1c2c3c4c5c6c7c4g5g'eSeTe:dQdQb8c9c!c#c6g(e7g)e8g9g!g*e#g+e$g%g'g,e(g-e)g*g.esg+g;d=dAb4d,g/e?dRb$c-g:e@dSb%cfcUeVe[d5d.g/gUdTb'c:g;g=g;e]dUb(c?g=e^dVb)c@g?e_dWb*c[g@e`dXb+c[eubGdHdCdsd]e^epcYbIb_e`e]g{e{dZb,cibwdxdkc|d}dcbBb~dae^g|ebe0b-c_g}ece1b.cbc] ~ `g~ede2b/c, dbeb_ 3b4b5b6b; CbDbpb:c;c/ =c?c{gafee7b@c|gbffe8b[c}gcfge9b]c~gdfhe!b^cgcWeXeie6dahbhXd#b_cchdhehefje$b`cfhffke%b{cghgfle'b|chhhfme(b}cifvbIdJdDdtdjfkfqc)bJblfmfihnfne*b~cjbydzdlcoepefbEbqerejhofse+badkhpfte,bbdcc^ ablhqfue-bcd- gbhb` .b/b:b;b= FbGbqbdded: fdgdmhrfve=bhdnhsfwe?bidohtfxe@bjdphufye[bkdqhvfze]bldrhwfAe^bmdshxfBe_bndthyfCe`boduhzfDe{bpdvhAfEe|bqdwhBfFe}brd
486 n._peer_access = peer_access 2qgrg$dCgDgEgFg0eGg1eHgIg%d'd(d)d*d% ' ( ) wbxbybzbJgKgLg2e3e4eMgNg5eIeJe+dLdLbsctcucvcsbOgtbPg6ehcKeicLejc,dkbMdbbMblbwcmbxcnbycobzcQg7eRg8eSgTgUg9eVg!eWgXgYgZg#eMeNe-dNdNbAcBcCcDcEc0gFc1gGc$eHcOeIcPeJc.dKcOdHbObLcMcNcOcPcQcRcScTc2gUc3gVc%eWcQeXcReYc/dZcPdPb0c1c2c3c4c5c6c7c4g5g'eSeTe:dQdQb8c9c!c#c6g(e7g)e8g9g!g*e#g+e$g%g'g,e(g-e)g*g.esg+g;d=dAb4d,g/e?dRb$c-g:e@dSb%cfcUeVe[d5d.g/gUdTb'c:g;g=g;e]dUb(c?g=e^dVb)c@g?e_dWb*c[g@e`dXb+c[eubGdHdCdsd]e^epcYbIb_e`e]g{e{dZb,cibwdxdkc|d}dcbBb~dae^g|ebe0b-c_g}ece1b.cbc] ~ `g~ede2b/c, dbeb_ 3b4b5b6b; CbDbpb:c;c/ =c?c{gafee7b@c|gbffe8b[c}gcfge9b]c~gdfhe!b^cgcWeXeie6dahbhXd#b_cchdhehefje$b`cfhffke%b{cghgfle'b|chhhfme(b}cifvbIdJdDdtdjfkfqc)bJblfmfihnfne*b~cjbydzdlcoepefbEbqerejhofse+badkhpfte,bbdcc^ ablhqfue-bcd- gbhb` .b/b:b;b= FbGbqbdded: fdgdmhrfve=bhdnhsfwe?bidohtfxe@bjdphufye[bkdqhvfze]bldrhwfAe^bmdshxfBe_bndthyfCe`boduhzfDe{bpdvhAfEe|bqdwhBfFe}brd
487 return n 2qgrg$dCgDgEgFg0eGg1eHgIg%d'd(d)d*d% ' ( ) wbxbybzbJgKgLg2e3e4eMgNg5eIeJe+dLdLbsctcucvcsbOgtbPg6ehcKeicLejc,dkbMdbbMblbwcmbxcnbycobzcQg7eRg8eSgTgUg9eVg!eWgXgYgZg#eMeNe-dNdNbAcBcCcDcEc0gFc1gGc$eHcOeIcPeJc.dKcOdHbObLcMcNcOcPcQcRcScTc2gUc3gVc%eWcQeXcReYc/dZcPdPb0c1c2c3c4c5c6c7c4g5g'eSeTe:dQdQb8c9c!c#c6g(e7g)e8g9g!g*e#g+e$g%g'g,e(g-e)g*g.esg+g;d=dAb4d,g/e?dRb$c-g:e@dSb%cfcUeVe[d5d.g/gUdTb'c:g;g=g;e]dUb(c?g=e^dVb)c@g?e_dWb*c[g@e`dXb+c[eubGdHdCdsd]e^epcYbIb_e`e]g{e{dZb,cibwdxdkc|d}dcbBb~dae^g|ebe0b-c_g}ece1b.cbc] ~ `g~ede2b/c, dbeb_ 3b4b5b6b; CbDbpb:c;c/ =c?c{gafee7b@c|gbffe8b[c}gcfge9b]c~gdfhe!b^cgcWeXeie6dahbhXd#b_cchdhehefje$b`cfhffke%b{cghgfle'b|chhhfme(b}cifvbIdJdDdtdjfkfqc)bJblfmfihnfne*b~cjbydzdlcoepefbEbqerejhofse+badkhpfte,bbdcc^ ablhqfue-bcd- gbhb` .b/b:b;b= FbGbqbdded: fdgdmhrfve=bhdnhsfwe?bidohtfxe@bjdphufye[bkdqhvfze]bldrhwfAe^bmdshxfBe_bndthyfCe`boduhzfDe{bpdvhAfEe|bqdwhBfFe}brd
489 @staticmethod
490 cdef AllocNode _create_from_driver(GraphNodeHandle h_node):
491 """Create by fetching params from the driver (called by _create factory)."""
492 cdef cydriver.CUgraphNode node = as_cu(h_node) 2sbtbhcicjckbbblbmbnbobEcFcGcHcIcJcKcHbLcNcPcRcTcUcVcWcXcYcZc0c2c4c6c
493 cdef cydriver.CUDA_MEM_ALLOC_NODE_PARAMS params
494 with nogil: 2sbtbhcicjckbbblbmbnbobEcFcGcHcIcJcKcHbLcNcPcRcTcUcVcWcXcYcZc0c2c4c6c
495 HANDLE_RETURN(cydriver.cuGraphMemAllocNodeGetParams(node, ¶ms)) 2sbtbhcicjckbbblbmbnbobEcFcGcHcIcJcKcHbLcNcPcRcTcUcVcWcXcYcZc0c2c4c6c
497 cdef str memory_type
498 if params.poolProps.allocType == cydriver.CUmemAllocationType.CU_MEM_ALLOCATION_TYPE_PINNED: 2sbtbhcicjckbbblbmbnbobEcFcGcHcIcJcKcHbLcNcPcRcTcUcVcWcXcYcZc0c2c4c6c
499 if params.poolProps.location.type == cydriver.CUmemLocationType.CU_MEM_LOCATION_TYPE_HOST: 2sbtbhcicjckbbblbmbnbobEcFcGcHcIcJcKcHbLcNcPcRcTcUcVcWcXcYcZc0c2c4c6c
500 memory_type = "host"
501 else:
502 memory_type = "device" 2sbtbhcicjckbbblbmbnbobEcFcGcHcIcJcKcHbLcNcPcRcTcUcVcWcXcYcZc0c2c4c6c
503 else:
504 IF CUDA_CORE_BUILD_MAJOR >= 13:
505 if params.poolProps.allocType == cydriver.CUmemAllocationType.CU_MEM_ALLOCATION_TYPE_MANAGED:
506 memory_type = "managed"
507 else:
508 memory_type = "device"
509 ELSE:
510 memory_type = "device"
512 cdef list peer_ids = [] 2sbtbhcicjckbbblbmbnbobEcFcGcHcIcJcKcHbLcNcPcRcTcUcVcWcXcYcZc0c2c4c6c
513 cdef size_t i
514 for i in range(params.accessDescCount): 2sbtbhcicjckbbblbmbnbobEcFcGcHcIcJcKcHbLcNcPcRcTcUcVcWcXcYcZc0c2c4c6c
515 peer_ids.append(<int>params.accessDescs[i].location.id)
517 return AllocNode._create_with_params( 2sbtbhcicjckbbblbmbnbobEcFcGcHcIcJcKcHbLcNcPcRcTcUcVcWcXcYcZc0c2c4c6c
518 h_node, params.dptr, params.bytesize,
519 <int>params.poolProps.location.id, memory_type, tuple(peer_ids)) 2sbtbhcicjckbbblbmbnbobEcFcGcHcIcJcKcHbLcNcPcRcTcUcVcWcXcYcZc0c2c4c6c
521 def __repr__(self) -> str:
522 return (f"<AllocNode handle=0x{as_intptr(self._h_node):x}" 2xk
523 f" dptr=0x{self._dptr:x} size={self._bytesize}>") 2xk
525 @property
526 def dptr(self) -> int:
527 """The device pointer for the allocation."""
528 return self._dptr 2qgrg$d%d'd(d)d*d% ' ( ) wbxbybzbbjcj+dLbsctcucvcsbtb,dMbwcxcyczc-dNbAcBcCcDc.dObMcOcQcSc/dPb1c3c5c7c:dQb8c9c!c#csgAb?dRb$c@dSb%c[dTb'c]dUb(c^dVb)c_dWb*c`dXb+cCdYbIb{dZb,cibwdxdkc|d}dcbBb~daebe0b-cce1b.cbc] ~ de2b/c, dbeb_ 3b4b5b6b; CbDbpb:c;c/ =c?cee7b@cfe8b[cge9b]che!b^cie#b_cje$b`cke%b{cle'b|cme(b}cDd)bJbne*b~cjbydzdlcoepefbEbqerese+badte,bbdcc^ abue-bcd- gbhb` .b/b:b;b= FbGbqbdded: fdgdve=bhdwe?bidxe@bjdye[bkdze]bldAe^bmdBe_bndCe`bodDe{bpdEe|bqdFe}brd
530 @property
531 def bytesize(self) -> int:
532 """The number of bytes allocated."""
533 return self._bytesize 2bjcjsbtb
535 @property
536 def device_id(self) -> int:
537 """The device on which the allocation was made."""
538 return self._device_id 2bjcjsbtb
540 @property
541 def memory_type(self) -> str:
542 """The type of memory: ``"device"``, ``"host"``, or ``"managed"``."""
543 return self._memory_type 2bjcjsbtb
545 @property
546 def peer_access(self) -> tuple[int, ...]:
547 """Device IDs with read-write access to this allocation."""
548 return self._peer_access 2bjcjsbtb
551cdef class FreeNode(GraphNode):
552 """A memory deallocation node.
554 Properties
555 ----------
556 dptr : int
557 The device pointer being freed.
558 """
560 @staticmethod
561 cdef FreeNode _create_with_params(GraphNodeHandle h_node,
562 cydriver.CUdeviceptr dptr):
563 """Create from known params (called by deallocate() builder)."""
564 cdef FreeNode n = FreeNode.__new__(FreeNode) 2$d%d'd(d)d*d% ' ( ) wbxbybzb+d,d-d.d/d:dAb?d@d[d]d^d_d`dCd{dibwdxdkc|d}dcbBb~daebecebcdeeefegeheiejekelemeDdnejbydzdlcoepefbEbqereseteccuevewexeyezeAeBeCeDeEeFe
565 n._h_node = h_node 2$d%d'd(d)d*d% ' ( ) wbxbybzb+d,d-d.d/d:dAb?d@d[d]d^d_d`dCd{dibwdxdkc|d}dcbBb~daebecebcdeeefegeheiejekelemeDdnejbydzdlcoepefbEbqereseteccuevewexeyezeAeBeCeDeEeFe
566 n._dptr = dptr 2$d%d'd(d)d*d% ' ( ) wbxbybzb+d,d-d.d/d:dAb?d@d[d]d^d_d`dCd{dibwdxdkc|d}dcbBb~daebecebcdeeefegeheiejekelemeDdnejbydzdlcoepefbEbqereseteccuevewexeyezeAeBeCeDeEeFe
567 return n 2$d%d'd(d)d*d% ' ( ) wbxbybzb+d,d-d.d/d:dAb?d@d[d]d^d_d`dCd{dibwdxdkc|d}dcbBb~daebecebcdeeefegeheiejekelemeDdnejbydzdlcoepefbEbqereseteccuevewexeyezeAeBeCeDeEeFe
569 @staticmethod
570 cdef FreeNode _create_from_driver(GraphNodeHandle h_node):
571 """Create by fetching params from the driver (called by _create factory)."""
572 cdef cydriver.CUgraphNode node = as_cu(h_node) 2Ab
573 cdef cydriver.CUdeviceptr dptr
574 with nogil: 2Ab
575 HANDLE_RETURN(cydriver.cuGraphMemFreeNodeGetParams(node, &dptr)) 2Ab
576 return FreeNode._create_with_params(h_node, dptr) 2Ab
578 def __repr__(self) -> str:
579 return f"<FreeNode handle=0x{as_intptr(self._h_node):x} dptr=0x{self._dptr:x}>" 2Ik
581 @property
582 def dptr(self) -> int:
583 """The device pointer being freed."""
584 return self._dptr 2JkjcAb
587cdef class MemsetNode(GraphNode):
588 """A memset node.
590 Properties
591 ----------
592 dptr : int
593 The destination device pointer.
594 value : int
595 The fill value.
596 element_size : int
597 Element size in bytes (1, 2, or 4).
598 width : int
599 Width of the row in elements.
600 height : int
601 Number of rows.
602 pitch : int
603 Pitch in bytes (unused if height is 1).
604 """
606 @staticmethod
607 cdef MemsetNode _create_with_params(GraphNodeHandle h_node,
608 cydriver.CUdeviceptr dptr, unsigned int value,
609 unsigned int element_size, size_t width,
610 size_t height, size_t pitch):
611 """Create from known params (called by memset() builder)."""
612 cdef MemsetNode n = MemsetNode.__new__(MemsetNode) 2% ' ( ) wbxbybzbsctcucvcwcxcyczcAcBcCcDcMcOcQcSc1c3c5c7c8c9c!c#ctgugvg? Yeh i # $ egfgR y z U V b Ada $c%c'c(c)c*c+cIb,cBb-c.c~ /c; CbDbpb:c;c/ =c?c@c[c]c^c_c`c{c|c}cJb~cEbadbdabcd= FbGbqbdded: fdgdhdidjdkdldmdndodpdqdrd
613 n._h_node = h_node 2% ' ( ) wbxbybzbsctcucvcwcxcyczcAcBcCcDcMcOcQcSc1c3c5c7c8c9c!c#ctgugvg? Yeh i # $ egfgR y z U V b Ada $c%c'c(c)c*c+cIb,cBb-c.c~ /c; CbDbpb:c;c/ =c?c@c[c]c^c_c`c{c|c}cJb~cEbadbdabcd= FbGbqbdded: fdgdhdidjdkdldmdndodpdqdrd
614 n._dptr = dptr 2% ' ( ) wbxbybzbsctcucvcwcxcyczcAcBcCcDcMcOcQcSc1c3c5c7c8c9c!c#ctgugvg? Yeh i # $ egfgR y z U V b Ada $c%c'c(c)c*c+cIb,cBb-c.c~ /c; CbDbpb:c;c/ =c?c@c[c]c^c_c`c{c|c}cJb~cEbadbdabcd= FbGbqbdded: fdgdhdidjdkdldmdndodpdqdrd
615 n._value = value 2% ' ( ) wbxbybzbsctcucvcwcxcyczcAcBcCcDcMcOcQcSc1c3c5c7c8c9c!c#ctgugvg? Yeh i # $ egfgR y z U V b Ada $c%c'c(c)c*c+cIb,cBb-c.c~ /c; CbDbpb:c;c/ =c?c@c[c]c^c_c`c{c|c}cJb~cEbadbdabcd= FbGbqbdded: fdgdhdidjdkdldmdndodpdqdrd
616 n._element_size = element_size 2% ' ( ) wbxbybzbsctcucvcwcxcyczcAcBcCcDcMcOcQcSc1c3c5c7c8c9c!c#ctgugvg? Yeh i # $ egfgR y z U V b Ada $c%c'c(c)c*c+cIb,cBb-c.c~ /c; CbDbpb:c;c/ =c?c@c[c]c^c_c`c{c|c}cJb~cEbadbdabcd= FbGbqbdded: fdgdhdidjdkdldmdndodpdqdrd
617 n._width = width 2% ' ( ) wbxbybzbsctcucvcwcxcyczcAcBcCcDcMcOcQcSc1c3c5c7c8c9c!c#ctgugvg? Yeh i # $ egfgR y z U V b Ada $c%c'c(c)c*c+cIb,cBb-c.c~ /c; CbDbpb:c;c/ =c?c@c[c]c^c_c`c{c|c}cJb~cEbadbdabcd= FbGbqbdded: fdgdhdidjdkdldmdndodpdqdrd
618 n._height = height 2% ' ( ) wbxbybzbsctcucvcwcxcyczcAcBcCcDcMcOcQcSc1c3c5c7c8c9c!c#ctgugvg? Yeh i # $ egfgR y z U V b Ada $c%c'c(c)c*c+cIb,cBb-c.c~ /c; CbDbpb:c;c/ =c?c@c[c]c^c_c`c{c|c}cJb~cEbadbdabcd= FbGbqbdded: fdgdhdidjdkdldmdndodpdqdrd
619 n._pitch = pitch 2% ' ( ) wbxbybzbsctcucvcwcxcyczcAcBcCcDcMcOcQcSc1c3c5c7c8c9c!c#ctgugvg? Yeh i # $ egfgR y z U V b Ada $c%c'c(c)c*c+cIb,cBb-c.c~ /c; CbDbpb:c;c/ =c?c@c[c]c^c_c`c{c|c}cJb~cEbadbdabcd= FbGbqbdded: fdgdhdidjdkdldmdndodpdqdrd
620 return n 2% ' ( ) wbxbybzbsctcucvcwcxcyczcAcBcCcDcMcOcQcSc1c3c5c7c8c9c!c#ctgugvg? Yeh i # $ egfgR y z U V b Ada $c%c'c(c)c*c+cIb,cBb-c.c~ /c; CbDbpb:c;c/ =c?c@c[c]c^c_c`c{c|c}cJb~cEbadbdabcd= FbGbqbdded: fdgdhdidjdkdldmdndodpdqdrd
622 @staticmethod
623 cdef MemsetNode _create_from_driver(GraphNodeHandle h_node):
624 """Create by fetching params from the driver (called by _create factory)."""
625 cdef cydriver.CUgraphNode node = as_cu(h_node) 1?
626 cdef cydriver.CUDA_MEMSET_NODE_PARAMS params
627 with nogil: 1?
628 HANDLE_RETURN(cydriver.cuGraphMemsetNodeGetParams(node, ¶ms)) 1?
629 return MemsetNode._create_with_params( 1?
630 h_node, params.dst, params.value,
631 params.elementSize, params.width, params.height, params.pitch) 1?
633 def __repr__(self) -> str:
634 return (f"<MemsetNode handle=0x{as_intptr(self._h_node):x}" 2yk
635 f" dptr=0x{self._dptr:x} value={self._value}>") 2yk
637 def update(
638 self,
639 *,
640 dst: Buffer | int | None = None,
641 value=None,
642 width: int | None = None,
643 height: int | None = None,
644 pitch: int | None = None,
645 dst_owner=None,
646 ) -> None:
647 """Replace selected memset parameters.
649 Omitted parameters preserve their current values. ``dst_owner`` may
650 only accompany a raw-address ``dst``.
652 With CUDA 12.2 through 13.1, the node's intended CUDA context must be
653 current when this method is called. CUDA driver and ``cuda.bindings``
654 versions 13.2 and newer preserve the recorded context automatically.
656 .. warning::
658 Use caution when a retained operand owner directly or indirectly
659 owns a graph. Any reference cycle involving the owner and a graph
660 that retains it cannot be broken by Python's cyclic garbage
661 collector. Use a weak reference to break such cycles.
662 """
663 cdef OpaqueHandle dst_attachment_owner
664 GN_check_valid(self) 2h i # $ egfgU V b a
665 cdef GraphHandle h_graph
666 cdef cydriver.CUgraphNode node = as_cu(self._h_node) 1hi#$UVba
667 cdef cydriver.CUcontext ctx = NULL 1hi#$UVba
668 cdef cydriver.CUDA_MEMSET_NODE_PARAMS current
669 cdef cydriver.CUgraphNodeParams params
670 cdef object queried
672 if dst is None and dst_owner is not None: 1hi#$UVba
673 raise ValueError("dst_owner requires dst") 1b
674 if (dst is None and value is None and width is None and 1hi#$UVba
675 height is None and pitch is None): 1b
676 return 1b
678 c_memset(¶ms, 0, sizeof(params)) 1hi#$UVba
679 params.type = cydriver.CU_GRAPH_NODE_TYPE_MEMSET 1hi#$UVba
680 with nogil: 1hi#$UVba
681 HANDLE_RETURN(cydriver.cuGraphMemsetNodeGetParams( 1hi#$UVba
682 node, ¤t))
683 if _check_node_get_params(): 1hi#$UVba
684 queried = handle_return(driver.cuGraphNodeGetParams( 1hi#$UVba
685 <uintptr_t>node)) 1hi#$UVba
686 ctx = <cydriver.CUcontext><uintptr_t>int(queried.memset.ctx) 1hi#$UVba
687 else:
688 with nogil:
689 HANDLE_RETURN(cydriver.cuCtxGetCurrent(&ctx))
691 cdef cydriver.CUdeviceptr c_dst = current.dst 1hi#$UVba
692 cdef unsigned int c_value = current.value 1hi#$UVba
693 cdef unsigned int c_element_size = current.elementSize 1hi#$UVba
694 cdef size_t c_width = current.width 1hi#$UVba
695 cdef size_t c_height = current.height 1hi#$UVba
696 cdef size_t c_pitch = current.pitch 1hi#$UVba
698 if dst is None: 1hi#$UVba
699 h_graph = graph_node_get_graph(self._h_node) 1iUVba
700 HANDLE_RETURN(graph_get_attachment( 1iUVba
701 h_graph, node,
702 &dst_attachment_owner, NULL))
703 else:
704 dst_attachment_owner = _resolve_memcpy_operand( 1h#$
705 dst, dst_owner, "dst", &c_dst) 1h#$
707 if value is not None: 1hiUVba
708 c_value, c_element_size = _parse_fill_value(value) 1hiUVa
709 if width is not None: 1hiba
710 c_width = width 1b
711 if height is not None: 1hiba
712 c_height = height 1b
713 if pitch is not None: 1hiba
714 c_pitch = pitch 1b
716 params.memset.dst = c_dst 1hiba
717 params.memset.value = c_value 1hiba
718 params.memset.elementSize = c_element_size 1hiba
719 params.memset.width = c_width 1hiba
720 params.memset.height = c_height 1hiba
721 params.memset.pitch = c_pitch 1hiba
722 params.memset.ctx = ctx 1hiba
724 _set_definition_node_params( 1hiba
725 self._h_node, ¶ms, dst_attachment_owner,
726 OpaqueHandle(), params.memset.ctx)
727 self._dptr = c_dst 1hiba
728 self._value = c_value 1hiba
729 self._element_size = c_element_size 1hiba
730 self._width = c_width 1hiba
731 self._height = c_height 1hiba
732 self._pitch = c_pitch 1hiba
734 @property
735 def dptr(self) -> int:
736 """The destination device pointer."""
737 return self._dptr 2minioipilbmbnbobYeh i y z U V
739 @property
740 def value(self) -> int:
741 """The fill value."""
742 return self._value 2minioipilbmbnbobYeh i y z U V b
744 @property
745 def element_size(self) -> int:
746 """Element size in bytes (1, 2, or 4)."""
747 return self._element_size 2minioipilbmbnbobh i y z U V
749 @property
750 def width(self) -> int:
751 """Width of the row in elements."""
752 return self._width 2minioipilbmbnbobYeh i y z U V b
754 @property
755 def height(self) -> int:
756 """Number of rows."""
757 return self._height 2minioipilbmbnbobh i y z U V b
759 @property
760 def pitch(self) -> int:
761 """Pitch in bytes (unused if height is 1)."""
762 return self._pitch 2minioipilbmbnbobh i y z U V b
765cdef class MemcpyNode(GraphNode):
766 """A memcpy node.
768 Properties
769 ----------
770 dst : int
771 The destination pointer.
772 src : int
773 The source pointer.
774 size : int
775 The number of bytes copied.
776 """
778 @staticmethod
779 cdef MemcpyNode _create_with_params(GraphNodeHandle h_node,
780 cydriver.CUdeviceptr dst, cydriver.CUdeviceptr src,
781 size_t size, cydriver.CUmemorytype dst_type,
782 cydriver.CUmemorytype src_type):
783 """Create from known params (called by memcpy() builder)."""
784 cdef MemcpyNode n = MemcpyNode.__new__(MemcpyNode) 2% ' ( ) LbMbNbObPbQbxhyhrb7dzhAhBhChDhEhc g d s t u ^f_f`fQ F G H n o p e f 7 b Ada RbSbTbUbVbWbXbYbZbcb0b1b] 2b, dbeb_ 3b4b5b6b/ 7b8b9b!b#b$b%b'b(b)b*bfb+b,b^ -b- gbhb` .b/b:b;b: =b?b@b[b]b^b_b`b{b|b}b
785 n._h_node = h_node 2% ' ( ) LbMbNbObPbQbxhyhrb7dzhAhBhChDhEhc g d s t u ^f_f`fQ F G H n o p e f 7 b Ada RbSbTbUbVbWbXbYbZbcb0b1b] 2b, dbeb_ 3b4b5b6b/ 7b8b9b!b#b$b%b'b(b)b*bfb+b,b^ -b- gbhb` .b/b:b;b: =b?b@b[b]b^b_b`b{b|b}b
786 n._dst = dst 2% ' ( ) LbMbNbObPbQbxhyhrb7dzhAhBhChDhEhc g d s t u ^f_f`fQ F G H n o p e f 7 b Ada RbSbTbUbVbWbXbYbZbcb0b1b] 2b, dbeb_ 3b4b5b6b/ 7b8b9b!b#b$b%b'b(b)b*bfb+b,b^ -b- gbhb` .b/b:b;b: =b?b@b[b]b^b_b`b{b|b}b
787 n._src = src 2% ' ( ) LbMbNbObPbQbxhyhrb7dzhAhBhChDhEhc g d s t u ^f_f`fQ F G H n o p e f 7 b Ada RbSbTbUbVbWbXbYbZbcb0b1b] 2b, dbeb_ 3b4b5b6b/ 7b8b9b!b#b$b%b'b(b)b*bfb+b,b^ -b- gbhb` .b/b:b;b: =b?b@b[b]b^b_b`b{b|b}b
788 n._size = size 2% ' ( ) LbMbNbObPbQbxhyhrb7dzhAhBhChDhEhc g d s t u ^f_f`fQ F G H n o p e f 7 b Ada RbSbTbUbVbWbXbYbZbcb0b1b] 2b, dbeb_ 3b4b5b6b/ 7b8b9b!b#b$b%b'b(b)b*bfb+b,b^ -b- gbhb` .b/b:b;b: =b?b@b[b]b^b_b`b{b|b}b
789 n._dst_type = dst_type 2% ' ( ) LbMbNbObPbQbxhyhrb7dzhAhBhChDhEhc g d s t u ^f_f`fQ F G H n o p e f 7 b Ada RbSbTbUbVbWbXbYbZbcb0b1b] 2b, dbeb_ 3b4b5b6b/ 7b8b9b!b#b$b%b'b(b)b*bfb+b,b^ -b- gbhb` .b/b:b;b: =b?b@b[b]b^b_b`b{b|b}b
790 n._src_type = src_type 2% ' ( ) LbMbNbObPbQbxhyhrb7dzhAhBhChDhEhc g d s t u ^f_f`fQ F G H n o p e f 7 b Ada RbSbTbUbVbWbXbYbZbcb0b1b] 2b, dbeb_ 3b4b5b6b/ 7b8b9b!b#b$b%b'b(b)b*bfb+b,b^ -b- gbhb` .b/b:b;b: =b?b@b[b]b^b_b`b{b|b}b
791 return n 2% ' ( ) LbMbNbObPbQbxhyhrb7dzhAhBhChDhEhc g d s t u ^f_f`fQ F G H n o p e f 7 b Ada RbSbTbUbVbWbXbYbZbcb0b1b] 2b, dbeb_ 3b4b5b6b/ 7b8b9b!b#b$b%b'b(b)b*bfb+b,b^ -b- gbhb` .b/b:b;b: =b?b@b[b]b^b_b`b{b|b}b
793 @staticmethod
794 cdef MemcpyNode _create_from_driver(GraphNodeHandle h_node):
795 """Create by fetching params from the driver (called by _create factory)."""
796 cdef cydriver.CUgraphNode node = as_cu(h_node) 2rb
797 cdef cydriver.CUDA_MEMCPY3D params
798 with nogil: 2rb
799 HANDLE_RETURN(cydriver.cuGraphMemcpyNodeGetParams(node, ¶ms)) 2rb
801 cdef cydriver.CUdeviceptr dst
802 cdef cydriver.CUdeviceptr src
803 if params.dstMemoryType == cydriver.CU_MEMORYTYPE_HOST: 2rb
804 dst = <cydriver.CUdeviceptr><uintptr_t>params.dstHost 2rb
805 else:
806 dst = params.dstDevice
807 if params.srcMemoryType == cydriver.CU_MEMORYTYPE_HOST: 2rb
808 src = <cydriver.CUdeviceptr><uintptr_t>params.srcHost 2rb
809 else:
810 src = params.srcDevice
812 return MemcpyNode._create_with_params( 2rb
813 h_node, dst, src, params.WidthInBytes,
814 params.dstMemoryType, params.srcMemoryType) 2rb
816 def __repr__(self) -> str:
817 cdef str dt = "H" if self._dst_type == cydriver.CU_MEMORYTYPE_HOST else "D" 2lj
818 cdef str st = "H" if self._src_type == cydriver.CU_MEMORYTYPE_HOST else "D" 2lj
819 return (f"<MemcpyNode handle=0x{as_intptr(self._h_node):x}" 2lj
820 f" dst=0x{self._dst:x}({dt}) src=0x{self._src:x}({st}) size={self._size}>") 2lj
822 def update(
823 self,
824 *,
825 dst: Buffer | int | None = None,
826 src: Buffer | int | None = None,
827 size: int | None = None,
828 dst_owner=None,
829 src_owner=None,
830 ) -> None:
831 """Replace selected memcpy parameters.
833 Omitted parameters preserve their current values. ``dst_owner`` and
834 ``src_owner`` may only accompany their corresponding raw addresses.
835 Multidimensional, pitched, offset, and array-backed memcpy nodes are
836 not supported.
838 With CUDA 12.2 through 13.1, the node's intended CUDA context must be
839 current when this method is called. CUDA driver and ``cuda.bindings``
840 versions 13.2 and newer preserve the recorded context automatically.
842 .. warning::
844 Use caution when a retained operand owner directly or indirectly
845 owns a graph. Any reference cycle involving the owner and a graph
846 that retains it cannot be broken by Python's cyclic garbage
847 collector. Use a weak reference to break such cycles.
848 """
849 cdef cydriver.CUdeviceptr c_dst = self._dst 2c g d s t u ^f_f`fn o p e f 7 b a
850 cdef cydriver.CUdeviceptr c_src = self._src 2c g d s t u ^f_f`fn o p e f 7 b a
851 cdef OpaqueHandle dst_attachment_owner
852 cdef OpaqueHandle src_attachment_owner
853 GN_check_valid(self) 2c g d s t u ^f_f`fn o p e f 7 b a
854 cdef GraphHandle h_graph = graph_node_get_graph(self._h_node) 1cgdstunopef7ba
855 cdef cydriver.CUgraphNode node = as_cu(self._h_node) 1cgdstunopef7ba
856 cdef cydriver.CUcontext ctx = NULL 1cgdstunopef7ba
857 cdef cydriver.CUgraphNodeParams params
858 cdef cydriver.CUmemorytype c_dst_type
859 cdef cydriver.CUmemorytype c_src_type
860 cdef object queried
862 if dst is None and dst_owner is not None: 1cgdstunopef7ba
863 raise ValueError("dst_owner requires dst") 1b
864 if src is None and src_owner is not None: 1cgdstunopef7ba
865 raise ValueError("src_owner requires src") 1b
866 if dst is None and src is None and size is None: 1cgdstunopef7ba
867 return 1b
869 c_memset(¶ms, 0, sizeof(params)) 1cgdstunopef7a
870 params.type = cydriver.CU_GRAPH_NODE_TYPE_MEMCPY 1cgdstunopef7a
871 with nogil: 1cgdstunopef7a
872 HANDLE_RETURN(cydriver.cuGraphMemcpyNodeGetParams( 1cgdstunopef7a
873 node, ¶ms.memcpy.copyParams))
874 if _check_node_get_params(): 1cgdstunopef7a
875 queried = handle_return(driver.cuGraphNodeGetParams( 1cgdstunopef7a
876 <uintptr_t>node)) 1cgdstunopef7a
877 ctx = <cydriver.CUcontext><uintptr_t>int( 1cgdstunopef7a
878 queried.memcpy.copyCtx) 1cgdstunopef7a
879 else:
880 with nogil:
881 HANDLE_RETURN(cydriver.cuCtxGetCurrent(&ctx))
882 params.memcpy.copyCtx = ctx 1cgdstunopef7a
884 if not _is_supported_memcpy_descriptor(¶ms.memcpy.copyParams): 1cgdstunopef7a
885 raise NotImplementedError( 17
886 "updating multidimensional, pitched, offset, or array-backed "
887 "memcpy nodes is not supported")
889 c_dst_type = params.memcpy.copyParams.dstMemoryType 1cgdstunopefa
890 c_src_type = params.memcpy.copyParams.srcMemoryType 1cgdstunopefa
891 if c_dst_type == cydriver.CU_MEMORYTYPE_HOST: 1cgdstunopefa
892 c_dst = <cydriver.CUdeviceptr><uintptr_t>( 1cgdstunopefa
893 params.memcpy.copyParams.dstHost)
894 elif c_dst_type == cydriver.CU_MEMORYTYPE_DEVICE:
895 c_dst = params.memcpy.copyParams.dstDevice
896 else:
897 raise NotImplementedError(
898 f"unsupported destination memory type: {int(c_dst_type)}")
899 if c_src_type == cydriver.CU_MEMORYTYPE_HOST: 1cgdstunopefa
900 c_src = <cydriver.CUdeviceptr><uintptr_t>( 1cgdstunopefa
901 params.memcpy.copyParams.srcHost)
902 elif c_src_type == cydriver.CU_MEMORYTYPE_DEVICE:
903 c_src = params.memcpy.copyParams.srcDevice
904 else:
905 raise NotImplementedError(
906 f"unsupported source memory type: {int(c_src_type)}")
908 HANDLE_RETURN(graph_get_attachment( 1cgdstunopefa
909 h_graph, node,
910 &dst_attachment_owner, &src_attachment_owner))
911 if dst is not None: 1cgdstunopefa
912 dst_attachment_owner = _resolve_memcpy_operand( 1cf
913 dst, dst_owner, "dst", &c_dst)
914 c_dst_type = _get_memcpy_memory_type(c_dst) 1cf
915 params.memcpy.copyParams.dstMemoryType = c_dst_type 1cf
916 params.memcpy.copyParams.dstHost = NULL 1cf
917 params.memcpy.copyParams.dstDevice = 0 1cf
918 params.memcpy.copyParams.dstArray = NULL 1cf
919 params.memcpy.copyParams.reserved1 = NULL 1cf
920 if c_dst_type == cydriver.CU_MEMORYTYPE_HOST: 1cf
921 params.memcpy.copyParams.dstHost = <void*><uintptr_t>c_dst 1c
922 else:
923 params.memcpy.copyParams.dstDevice = c_dst 1f
924 if src is not None: 1cgdstunopefa
925 src_attachment_owner = _resolve_memcpy_operand( 1dstue
926 src, src_owner, "src", &c_src)
927 c_src_type = _get_memcpy_memory_type(c_src) 1de
928 params.memcpy.copyParams.srcMemoryType = c_src_type 1de
929 params.memcpy.copyParams.srcHost = NULL 1de
930 params.memcpy.copyParams.srcDevice = 0 1de
931 params.memcpy.copyParams.srcArray = NULL 1de
932 params.memcpy.copyParams.reserved0 = NULL 1de
933 if c_src_type == cydriver.CU_MEMORYTYPE_HOST: 1de
934 params.memcpy.copyParams.srcHost = <void*><uintptr_t>c_src 1d
935 else:
936 params.memcpy.copyParams.srcDevice = c_src 1e
937 if size is not None: 1cgdnopefa
938 params.memcpy.copyParams.WidthInBytes = size 1gnopa
940 _set_definition_node_params( 1cgdefa
941 self._h_node, ¶ms,
942 dst_attachment_owner, src_attachment_owner,
943 params.memcpy.copyCtx)
944 self._dst = c_dst 1cgdefa
945 self._src = c_src 1cgdefa
946 self._size = params.memcpy.copyParams.WidthInBytes 1cgdefa
947 self._dst_type = c_dst_type 1cgdefa
948 self._src_type = c_src_type 1cgdefa
950 @property
951 def dst(self) -> int:
952 """The destination pointer."""
953 return self._dst 2vkbbrbc g d F G H n o p b
955 @property
956 def src(self) -> int:
957 """The source pointer."""
958 return self._src 2vkbbrbc g d F G H n o p b
960 @property
961 def size(self) -> int:
962 """The number of bytes copied."""
963 return self._size 2vkbbrbc g d F G H n o p b
966cdef class ChildGraphNode(GraphNode):
967 """A child graph node.
969 Properties
970 ----------
971 child_graph : GraphDefinition
972 The embedded graph definition (non-owning wrapper).
973 """
975 @staticmethod
976 cdef ChildGraphNode _create_with_params(GraphNodeHandle h_node,
977 GraphHandle h_child_graph):
978 """Create from known params (called by embed() builder)."""
979 cdef ChildGraphNode n = ChildGraphNode.__new__(ChildGraphNode) 2mcCfDfEfFfGfHfIf@ ecC dj| gg[ { Kb} E cgL W {fZeB ! JfKffcLfVdWdudMfNfOfPfQfRfSfubTfibUfVfWfZf, ; 0f1f2f3fgc4fYdZdvd5f6f7f8f9f!f#fvb$fjb%f'f(f+f- = ,f-f.f/f:f;f=f?f@f[f]f
980 n._h_node = h_node 2mcCfDfEfFfGfHfIf@ ecC dj| gg[ { Kb} E cgL W {fZeB ! JfKffcLfVdWdudMfNfOfPfQfRfSfubTfibUfVfWfZf, ; 0f1f2f3fgc4fYdZdvd5f6f7f8f9f!f#fvb$fjb%f'f(f+f- = ,f-f.f/f:f;f=f?f@f[f]f
981 n._h_child_graph = h_child_graph 2mcCfDfEfFfGfHfIf@ ecC dj| gg[ { Kb} E cgL W {fZeB ! JfKffcLfVdWdudMfNfOfPfQfRfSfubTfibUfVfWfZf, ; 0f1f2f3fgc4fYdZdvd5f6f7f8f9f!f#fvb$fjb%f'f(f+f- = ,f-f.f/f:f;f=f?f@f[f]f
982 return n 2mcCfDfEfFfGfHfIf@ ecC dj| gg[ { Kb} E cgL W {fZeB ! JfKffcLfVdWdudMfNfOfPfQfRfSfubTfibUfVfWfZf, ; 0f1f2f3fgc4fYdZdvd5f6f7f8f9f!f#fvb$fjb%f'f(f+f- = ,f-f.f/f:f;f=f?f@f[f]f
984 @staticmethod
985 cdef ChildGraphNode _create_from_driver(GraphNodeHandle h_node):
986 """Create by fetching params from the driver (called by _create factory)."""
987 cdef cydriver.CUgraphNode node = as_cu(h_node) 1@C|[{}E
988 cdef cydriver.CUgraph child_graph = NULL 1@C|[{}E
989 with nogil: 1@C|[{}E
990 HANDLE_RETURN(cydriver.cuGraphChildGraphNodeGetGraph(node, &child_graph)) 1@C|[{}E
991 cdef GraphHandle h_graph = graph_node_get_graph(h_node) 1@C|[{}E
992 cdef GraphHandle h_child = create_child_graph_handle( 1@C|[{}E
993 child_graph, h_graph, node)
994 return ChildGraphNode._create_with_params(h_node, h_child) 1@C|[{}E
996 def __repr__(self) -> str:
997 return (f"<ChildGraphNode handle=0x{as_intptr(self._h_node):x}" 2@ C [ KbcgL zk
998 f" child=0x{as_intptr(self._h_child_graph):x}>") 2@ C [ KbcgL zk
1000 def update(self, child: GraphDefinition) -> None:
1001 """Replace the embedded graph with a clone of ``child``.
1003 ``child`` must belong to an independent graph hierarchy.
1004 """
1005 GN_check_valid(self) 2C E W Ze!
1006 GD_check_valid(child) 1CEW!
1007 cdef GraphHandle h_parent = graph_node_get_graph(self._h_node) 1CEW!
1008 cdef GraphHandle h_replacement
1009 cdef cydriver.CUgraphNode node = as_cu(self._h_node) 1CEW!
1010 cdef cydriver.CUgraphNodeParams params
1011 cdef cydriver.CUresult commit_status
1012 cdef PreparedChildGraphUpdate prepared
1014 _require_graph_node_update_support() 1CEW!
1015 c_memset(¶ms, 0, sizeof(params)) 1CEW!
1016 params.type = cydriver.CU_GRAPH_NODE_TYPE_GRAPH 1CEW!
1017 params.graph.graph = as_cu(child._h_graph) 1CEW!
1019 HANDLE_RETURN(graph_prepare_child_graph_update( 1CEW!
1020 h_parent, self._h_child_graph, node,
1021 child._h_graph, &prepared))
1022 with nogil: 1CEW
1023 HANDLE_RETURN(cydriver.cuGraphNodeSetParams( 1CEW
1024 node, ¶ms))
1025 try: 1CEW
1026 commit_status = graph_commit_child_graph_update( 1CEW
1027 prepared, &h_replacement)
1028 finally:
1029 if h_replacement: 1CEW
1030 self._h_child_graph = h_replacement 1CEW
1031 HANDLE_RETURN(commit_status) 1CEW
1033 @property
1034 def child_graph(self) -> GraphDefinition:
1035 """The embedded graph definition (non-owning wrapper)."""
1036 return GraphDefinition._from_handle(self._h_child_graph) 2mcKdKk@ ecC dj| [ { Kb} E cgW {fZeB !
1039cdef class EventRecordNode(GraphNode):
1040 """An event record node.
1042 Properties
1043 ----------
1044 event : Event
1045 The event being recorded.
1046 """
1048 @staticmethod
1049 cdef EventRecordNode _create_with_params(GraphNodeHandle h_node,
1050 EventHandle h_event):
1051 """Create from known params (called by record() builder)."""
1052 cdef EventRecordNode n = EventRecordNode.__new__(EventRecordNode) 2FhIeKeMeOeQeSeej;dfjGhHh8d9dAbrbHe0 O hgncJ D GeBdmjnjUeojVdpjqjrjGdsjIhigtjujvjwjwdxjyjXfzjdbCbAjBjCjDjWeEjYdFjGjHjIdIjJhjgJjKjLjMjydNjOj)fPjgbFbQjRjSjTjUjVjWjXjYjZj0j
1053 n._h_node = h_node 2FhIeKeMeOeQeSeej;dfjGhHh8d9dAbrbHe0 O hgncJ D GeBdmjnjUeojVdpjqjrjGdsjIhigtjujvjwjwdxjyjXfzjdbCbAjBjCjDjWeEjYdFjGjHjIdIjJhjgJjKjLjMjydNjOj)fPjgbFbQjRjSjTjUjVjWjXjYjZj0j
1054 n._h_event = h_event 2FhIeKeMeOeQeSeej;dfjGhHh8d9dAbrbHe0 O hgncJ D GeBdmjnjUeojVdpjqjrjGdsjIhigtjujvjwjwdxjyjXfzjdbCbAjBjCjDjWeEjYdFjGjHjIdIjJhjgJjKjLjMjydNjOj)fPjgbFbQjRjSjTjUjVjWjXjYjZj0j
1055 return n 2FhIeKeMeOeQeSeej;dfjGhHh8d9dAbrbHe0 O hgncJ D GeBdmjnjUeojVdpjqjrjGdsjIhigtjujvjwjwdxjyjXfzjdbCbAjBjCjDjWeEjYdFjGjHjIdIjJhjgJjKjLjMjydNjOj)fPjgbFbQjRjSjTjUjVjWjXjYjZj0j
1057 @staticmethod
1058 cdef EventRecordNode _create_from_driver(GraphNodeHandle h_node):
1059 """Create by fetching params from the driver (called by _create factory)."""
1060 cdef cydriver.CUgraphNode node = as_cu(h_node) 28d
1061 cdef cydriver.CUevent event
1062 with nogil: 28d
1063 HANDLE_RETURN(cydriver.cuGraphEventRecordNodeGetEvent(node, &event)) 28d
1064 cdef EventHandle h_event = create_event_handle_ref(event) 28d
1065 return EventRecordNode._create_with_params(h_node, h_event) 28d
1067 def __repr__(self) -> str:
1068 return (f"<EventRecordNode handle=0x{as_intptr(self._h_node):x}" 2Ak
1069 f" event=0x{as_intptr(self._h_event):x}>") 2Ak
1071 def update(self, event: Event) -> None:
1072 """Replace the event recorded by this node."""
1073 GN_check_valid(self) 20 ncGe
1074 Event_check_open(event) 20 Ge
1075 cdef OpaqueHandle event_owner = event._h_event 10
1076 cdef cydriver.CUgraphNodeParams params
1078 c_memset(¶ms, 0, sizeof(params)) 10
1079 params.type = cydriver.CU_GRAPH_NODE_TYPE_EVENT_RECORD 10
1080 params.eventRecord.event = as_cu(event._h_event) 10
1082 _set_definition_node_params( 10
1083 self._h_node, ¶ms, event_owner)
1084 self._h_event = event._h_event 10
1086 @property
1087 def event(self) -> Event:
1088 """The event being recorded."""
1089 return Event._from_handle(self._h_event) 2Lkhcej;dfj8d0 J Ge
1092cdef class EventWaitNode(GraphNode):
1093 """An event wait node.
1095 Properties
1096 ----------
1097 event : Event
1098 The event being waited on.
1099 """
1101 @staticmethod
1102 cdef EventWaitNode _create_with_params(GraphNodeHandle h_node,
1103 EventHandle h_event):
1104 """Create from known params (called by wait() builder)."""
1105 cdef EventWaitNode n = EventWaitNode.__new__(EventWaitNode) 2FhJeLeNePeReTeGhHh=dgj8d9dO kgocD Bd1j2jVe3jWd4j5j6jHd7jIhlg8j9j!j#jxd$j%jYf'jebDb(j)j*j+jXe,jZd-j.j/jJd:jJhmg;j=j?j@jzd[j]j*f^jhbGb_j`j{j|j}j~jakbkckdkek
1106 n._h_node = h_node 2FhJeLeNePeReTeGhHh=dgj8d9dO kgocD Bd1j2jVe3jWd4j5j6jHd7jIhlg8j9j!j#jxd$j%jYf'jebDb(j)j*j+jXe,jZd-j.j/jJd:jJhmg;j=j?j@jzd[j]j*f^jhbGb_j`j{j|j}j~jakbkckdkek
1107 n._h_event = h_event 2FhJeLeNePeReTeGhHh=dgj8d9dO kgocD Bd1j2jVe3jWd4j5j6jHd7jIhlg8j9j!j#jxd$j%jYf'jebDb(j)j*j+jXe,jZd-j.j/jJd:jJhmg;j=j?j@jzd[j]j*f^jhbGb_j`j{j|j}j~jakbkckdkek
1108 return n 2FhJeLeNePeReTeGhHh=dgj8d9dO kgocD Bd1j2jVe3jWd4j5j6jHd7jIhlg8j9j!j#jxd$j%jYf'jebDb(j)j*j+jXe,jZd-j.j/jJd:jJhmg;j=j?j@jzd[j]j*f^jhbGb_j`j{j|j}j~jakbkckdkek
1110 @staticmethod
1111 cdef EventWaitNode _create_from_driver(GraphNodeHandle h_node):
1112 """Create by fetching params from the driver (called by _create factory)."""
1113 cdef cydriver.CUgraphNode node = as_cu(h_node) 29d
1114 cdef cydriver.CUevent event
1115 with nogil: 29d
1116 HANDLE_RETURN(cydriver.cuGraphEventWaitNodeGetEvent(node, &event)) 29d
1117 cdef EventHandle h_event = create_event_handle_ref(event) 29d
1118 return EventWaitNode._create_with_params(h_node, h_event) 29d
1120 def __repr__(self) -> str:
1121 return (f"<EventWaitNode handle=0x{as_intptr(self._h_node):x}" 2Bk
1122 f" event=0x{as_intptr(self._h_event):x}>") 2Bk
1124 def update(self, event: Event) -> None:
1125 """Replace the event waited on by this node."""
1126 GN_check_valid(self) 2O ocBd
1127 Event_check_open(event) 2O Bd
1128 cdef OpaqueHandle event_owner = event._h_event 1O
1129 cdef cydriver.CUgraphNodeParams params
1131 c_memset(¶ms, 0, sizeof(params)) 1O
1132 params.type = cydriver.CU_GRAPH_NODE_TYPE_WAIT_EVENT 1O
1133 params.eventWait.event = as_cu(event._h_event) 1O
1135 _set_definition_node_params( 1O
1136 self._h_node, ¶ms, event_owner)
1137 self._h_event = event._h_event 1O
1139 @property
1140 def event(self) -> Event:
1141 """The event being waited on."""
1142 return Event._from_handle(self._h_event) 2Mkic=dgj9dO D Bd
1145cdef class HostCallbackNode(GraphNode):
1146 """A host callback node.
1148 Properties
1149 ----------
1150 callback : callable or None
1151 The Python callable (None for ctypes function pointer callbacks).
1152 """
1154 @staticmethod
1155 cdef HostCallbackNode _create_with_params(GraphNodeHandle h_node,
1156 object callable_obj, cydriver.CUhostFn fn,
1157 void* user_data):
1158 """Create from known params (called by callback() builder)."""
1159 cdef HostCallbackNode n = HostCallbackNode.__new__(HostCallbackNode) 2qirisitiuiKhmcviwixiyiziAiBiCiDiEiFiGiHiIiJi@ KiLiMiNiC | ggX 1 3 4 5 2 Y 6 7d[ OiKbPi} E Qi4dL q ngW 0 O 8 9 {fhgkgRiLhZencochiiiP B J D M N S ! GeBdwgxgK r T I ogpgSiTiUi5dViudWiXiYisdZiiglgkc0i1i2i3i4i5i!d6i_ pb7i8i9i!i6d#ivd$i%i'itd(ijgmglc)i*i+i,i-i.i#d/i` qb:i;i=i?i@i[i]i^i_i`i{i
1160 n._h_node = h_node 2qirisitiuiKhmcviwixiyiziAiBiCiDiEiFiGiHiIiJi@ KiLiMiNiC | ggX 1 3 4 5 2 Y 6 7d[ OiKbPi} E Qi4dL q ngW 0 O 8 9 {fhgkgRiLhZencochiiiP B J D M N S ! GeBdwgxgK r T I ogpgSiTiUi5dViudWiXiYisdZiiglgkc0i1i2i3i4i5i!d6i_ pb7i8i9i!i6d#ivd$i%i'itd(ijgmglc)i*i+i,i-i.i#d/i` qb:i;i=i?i@i[i]i^i_i`i{i
1161 n._callable = callable_obj 2qirisitiuiKhmcviwixiyiziAiBiCiDiEiFiGiHiIiJi@ KiLiMiNiC | ggX 1 3 4 5 2 Y 6 7d[ OiKbPi} E Qi4dL q ngW 0 O 8 9 {fhgkgRiLhZencochiiiP B J D M N S ! GeBdwgxgK r T I ogpgSiTiUi5dViudWiXiYisdZiiglgkc0i1i2i3i4i5i!d6i_ pb7i8i9i!i6d#ivd$i%i'itd(ijgmglc)i*i+i,i-i.i#d/i` qb:i;i=i?i@i[i]i^i_i`i{i
1162 n._fn = fn 2qirisitiuiKhmcviwixiyiziAiBiCiDiEiFiGiHiIiJi@ KiLiMiNiC | ggX 1 3 4 5 2 Y 6 7d[ OiKbPi} E Qi4dL q ngW 0 O 8 9 {fhgkgRiLhZencochiiiP B J D M N S ! GeBdwgxgK r T I ogpgSiTiUi5dViudWiXiYisdZiiglgkc0i1i2i3i4i5i!d6i_ pb7i8i9i!i6d#ivd$i%i'itd(ijgmglc)i*i+i,i-i.i#d/i` qb:i;i=i?i@i[i]i^i_i`i{i
1163 n._user_data = user_data 2qirisitiuiKhmcviwixiyiziAiBiCiDiEiFiGiHiIiJi@ KiLiMiNiC | ggX 1 3 4 5 2 Y 6 7d[ OiKbPi} E Qi4dL q ngW 0 O 8 9 {fhgkgRiLhZencochiiiP B J D M N S ! GeBdwgxgK r T I ogpgSiTiUi5dViudWiXiYisdZiiglgkc0i1i2i3i4i5i!d6i_ pb7i8i9i!i6d#ivd$i%i'itd(ijgmglc)i*i+i,i-i.i#d/i` qb:i;i=i?i@i[i]i^i_i`i{i
1164 return n 2qirisitiuiKhmcviwixiyiziAiBiCiDiEiFiGiHiIiJi@ KiLiMiNiC | ggX 1 3 4 5 2 Y 6 7d[ OiKbPi} E Qi4dL q ngW 0 O 8 9 {fhgkgRiLhZencochiiiP B J D M N S ! GeBdwgxgK r T I ogpgSiTiUi5dViudWiXiYisdZiiglgkc0i1i2i3i4i5i!d6i_ pb7i8i9i!i6d#ivd$i%i'itd(ijgmglc)i*i+i,i-i.i#d/i` qb:i;i=i?i@i[i]i^i_i`i{i
1166 @staticmethod
1167 cdef HostCallbackNode _create_from_driver(GraphNodeHandle h_node):
1168 """Create by fetching params from the driver (called by _create factory)."""
1169 cdef cydriver.CUgraphNode node = as_cu(h_node) 2mc@ C | [ Kb} E W ncocB !
1170 cdef cydriver.CUDA_HOST_NODE_PARAMS params
1171 with nogil: 2mc@ C | [ Kb} E W ncocB !
1172 HANDLE_RETURN(cydriver.cuGraphHostNodeGetParams(node, ¶ms)) 2mc@ C | [ Kb} E W ncocB !
1174 cdef object callable_obj = None 2mc@ C | [ Kb} E W ncocB !
1175 if _is_py_host_trampoline(params.fn): 2mc@ C | [ Kb} E W ncocB !
1176 callable_obj = <object>params.userData 2mc@ C | [ Kb} E W ncocB !
1178 return HostCallbackNode._create_with_params( 2mc@ C | [ Kb} E W ncocB !
1179 h_node, callable_obj, params.fn, params.userData) 2mc@ C | [ Kb} E W ncocB !
1181 def __repr__(self) -> str:
1182 if self._callable is not None: 2ngI fk
1183 name = getattr(self._callable, '__name__', '?') 2I fk
1184 return (f"<HostCallbackNode handle=0x{as_intptr(self._h_node):x}" 2I fk
1185 f" callback={name}>") 2I fk
1186 return (f"<HostCallbackNode handle=0x{as_intptr(self._h_node):x}" 2ng
1187 f" cfunc=0x{<uintptr_t>self._fn:x}>") 2ng
1189 def update(self, fn, *, user_data=None) -> None:
1190 """Replace the callback and user-data binding for this node.
1192 ``fn`` accepts the same forms as :meth:`~graph.GraphNode.callback`: a
1193 Python callable, or a ctypes function pointer whose declared prototype
1194 matches ``CUhostFn`` (``void (*)(void*)``). A mismatched ctypes
1195 prototype raises ``TypeError``.
1197 .. warning::
1199 Callbacks must not call CUDA API functions. Doing so may
1200 deadlock or corrupt driver state.
1202 Use caution when a Python callback retains an object that owns a
1203 graph. Any reference cycle involving the callback and a graph that
1204 retains it cannot be broken by Python's cyclic garbage collector.
1205 Use a weak reference to break such cycles.
1206 """
1207 GN_check_valid(self) 2Kh8 9 Lhhiiiwgxg
1208 cdef cydriver.CUhostFn c_fn
1209 cdef void* c_user_data
1210 cdef OpaqueHandle fn_owner, data_owner
1211 cdef cydriver.CUgraphNodeParams params
1213 _resolve_host_callback( 2Kh8 9 Lhwgxg
1214 fn, user_data, &c_fn, &c_user_data, &fn_owner, &data_owner)
1215 c_memset(¶ms, 0, sizeof(params)) 189
1216 params.type = cydriver.CU_GRAPH_NODE_TYPE_HOST 189
1217 params.host.fn = c_fn 189
1218 params.host.userData = c_user_data 189
1220 _set_definition_node_params( 189
1221 self._h_node, ¶ms, fn_owner, data_owner)
1222 self._callable = fn if _is_py_host_trampoline(c_fn) else None 189
1223 self._fn = c_fn 189
1224 self._user_data = c_user_data 189
1226 @property
1227 def callback(self):
1228 """The Python callable, or None for ctypes function pointer callbacks."""
1229 return self._callable 2NkOkC ngW 8 9 B M N ! wgxg
1232cdef class ConditionalNode(GraphNode):
1233 """Base class for conditional nodes.
1235 When created via builder methods (if_then, if_else, while_loop, switch),
1236 a specific subclass (IfNode, IfElseNode, WhileNode, SwitchNode) is
1237 returned. When reconstructed from the driver on CUDA 13.2+, the
1238 correct subclass is determined via cuGraphNodeGetParams. On older
1239 drivers, this base class is used as a fallback.
1241 Properties
1242 ----------
1243 condition : GraphCondition or None
1244 The condition variable controlling execution (None pre-13.2).
1245 cond_type : str or None
1246 The conditional type ("if", "while", or "switch"; None pre-13.2).
1247 branches : tuple of GraphDefinition
1248 The body graphs for each branch (empty pre-13.2).
1249 """
1251 @staticmethod
1252 cdef ConditionalNode _create_from_driver(GraphNodeHandle h_node):
1253 cdef ConditionalNode n
1254 if not _check_node_get_params(): 1X13452Y6.
1255 n = ConditionalNode.__new__(ConditionalNode)
1256 n._h_node = h_node
1257 n._condition = None
1258 n._cond_type = cydriver.CU_GRAPH_COND_TYPE_IF
1259 n._branches = ()
1260 return n
1262 cdef cydriver.CUgraphNode node = as_cu(h_node) 1X13452Y6.
1263 params = handle_return(driver.cuGraphNodeGetParams( 1X13452Y6.
1264 <uintptr_t>node)) 1X13452Y6.
1265 cond_params = params.conditional 1X13452Y6.
1266 cdef int cond_type_int = int(cond_params.type) 1X13452Y6.
1267 cdef unsigned int size = int(cond_params.size) 1X13452Y6.
1269 cdef GraphCondition condition = GraphCondition.__new__(GraphCondition) 1X13452Y6.
1270 condition._c_handle = <cydriver.CUgraphConditionalHandle>( 1X13452Y6.
1271 <unsigned long long>int(cond_params.handle)) 1X13452Y6.
1273 cdef GraphHandle h_graph = graph_node_get_graph(h_node) 1X13452Y6.
1274 cdef list branch_list = [] 1X13452Y6.
1275 cdef unsigned int i
1276 cdef GraphHandle h_branch
1277 if cond_params.phGraph_out is not None: 1X13452Y6.
1278 for i in range(size): 1X13452Y6.
1279 h_branch = create_child_graph_handle( 1X13452Y6.
1280 <cydriver.CUgraph><uintptr_t>int(cond_params.phGraph_out[i]), 1X13452Y6.
1281 h_graph, node)
1282 branch_list.append(GraphDefinition._from_handle(h_branch)) 1X13452Y6.
1283 cdef tuple branches = tuple(branch_list) 1X13452Y6.
1285 cdef type cls
1286 if cond_type_int == <int>cydriver.CU_GRAPH_COND_TYPE_IF: 1X13452Y6.
1287 if size == 1: 1X152
1288 cls = IfNode 1X5
1289 else:
1290 cls = IfElseNode 112
1291 elif cond_type_int == <int>cydriver.CU_GRAPH_COND_TYPE_WHILE: 134Y6.
1292 cls = WhileNode 146.
1293 else:
1294 cls = SwitchNode 13Y
1296 n = cls.__new__(cls) 1X13452Y6.
1297 n._h_node = h_node 1X13452Y6.
1298 n._condition = condition 1X13452Y6.
1299 n._cond_type = <cydriver.CUgraphConditionalNodeType>cond_type_int 1X13452Y6.
1300 n._branches = branches 1X13452Y6.
1301 return n 1X13452Y6.
1303 def __repr__(self) -> str:
1304 return f"<ConditionalNode handle=0x{as_intptr(self._h_node):x}>"
1306 @property
1307 def condition(self) -> GraphCondition | None:
1308 """The condition variable controlling execution."""
1309 return self._condition 2ji|ihj}iki~iijaj
1311 @property
1312 def cond_type(self) -> GraphConditionalType | None:
1313 """The conditional type: GraphConditionalType.IF, .WHILE, or .SWITCH
1315 Returns None when reconstructed from the driver pre-CUDA 13.2,
1316 as the conditional type cannot be determined.
1317 """
1318 if self._condition is None: 2ji|ihj}iki~iijaj
1319 return None
1320 if self._cond_type == cydriver.CU_GRAPH_COND_TYPE_IF: 2ji|ihj}iki~iijaj
1321 return GraphConditionalType("if") 2ji|iki~i
1322 elif self._cond_type == cydriver.CU_GRAPH_COND_TYPE_WHILE:
1323 return GraphConditionalType("while") 2}iaj
1324 else:
1325 return GraphConditionalType("switch") 2hjij
1327 @property
1328 def branches(self) -> tuple[GraphDefinition, ...]:
1329 """The body graphs for each branch as a tuple of GraphDefinition.
1331 Returns an empty tuple when reconstructed from the driver
1332 pre-CUDA 13.2.
1333 """
1334 return self._branches 2ji|ihj}iki~iijajPkSd3 Y .
1337cdef class IfNode(ConditionalNode):
1338 """An if-conditional node."""
1340 def __repr__(self) -> str:
1341 return (f"<IfNode handle=0x{as_intptr(self._h_node):x}" 2Ck
1342 f" condition=0x{<unsigned long long>self._condition._c_handle:x}>") 2Ck
1344 @property
1345 def then(self) -> GraphDefinition:
1346 """The 'then' branch graph."""
1347 return self._branches[0] 2|i~iQkRdX 5
1350cdef class IfElseNode(ConditionalNode):
1351 """An if-else conditional node."""
1353 def __repr__(self) -> str:
1354 return (f"<IfElseNode handle=0x{as_intptr(self._h_node):x}" 2Dk
1355 f" condition=0x{<unsigned long long>self._condition._c_handle:x}>") 2Dk
1357 @property
1358 def then(self) -> GraphDefinition:
1359 """The ``then`` branch graph (executed when condition is non-zero)."""
1360 return self._branches[0] 2jikiEkEd1 2
1362 @property
1363 def else_(self) -> GraphDefinition:
1364 """The ``else`` branch graph (executed when condition is zero)."""
1365 return self._branches[1] 2jikiEkEd1 2
1368cdef class WhileNode(ConditionalNode):
1369 """A while-loop conditional node."""
1371 def __repr__(self) -> str:
1372 return (f"<WhileNode handle=0x{as_intptr(self._h_node):x}" 2Fk
1373 f" condition=0x{<unsigned long long>self._condition._c_handle:x}>") 2Fk
1375 @property
1376 def body(self) -> GraphDefinition:
1377 """The loop body graph."""
1378 return self._branches[0] 2}iajRkTd4 6
1381cdef class SwitchNode(ConditionalNode):
1382 """A switch conditional node."""
1384 def __repr__(self) -> str:
1385 return (f"<SwitchNode handle=0x{as_intptr(self._h_node):x}" 2Gk
1386 f" condition=0x{<unsigned long long>self._condition._c_handle:x}>") 2Gk
1389cdef class ExecutableGraphNode:
1390 """A lightweight view pairing an executable graph with a source node.
1392 Create executable-node views with ``graph[node]``. CUDA validates that the
1393 node identifies a node in the executable graph when an operation is
1394 performed.
1395 """
1397 def __init__(self):
1398 raise RuntimeError( 2Sk
1399 "directly constructing an executable graph node is not supported")
1401 def __repr__(self) -> str:
1402 return ( 2rc
1403 f"<{type(self).__name__} graph=0x{as_intptr(self._h_graph_exec):x}" 2rc
1404 f" node=0x{as_intptr(self._h_node):x}>" 2rc
1405 )
1408cdef class ExecutableKernelNode(ExecutableGraphNode):
1409 """An executable kernel-node view."""
1411 def update(
1412 self,
1413 *,
1414 config: LaunchConfig,
1415 kernel: Kernel,
1416 args,
1417 ) -> None:
1418 """Replace all kernel launch parameters for future launches.
1420 ``args`` must contain the complete argument sequence; use ``args=()``
1421 for a no-argument kernel. Clustered and cooperative launch
1422 configurations are not supported.
1423 """
1424 cdef LaunchConfig c_config = config 2q ~bacv w x r A
1425 cdef Kernel c_kernel = kernel 2q ~bacv w x r A
1426 cdef ParamHolder arg_holder
1427 cdef object kernel_args
1428 cdef OpaqueHandle kernel_owner = c_kernel._h_kernel 2q ~bacv w x r A
1429 cdef OpaqueHandle args_owner
1430 cdef cydriver.CUgraphNodeParams params
1432 if c_config.cluster is not None or c_config.is_cooperative: 2q ~bacv w x r A
1433 raise NotImplementedError( 2~bac
1434 "updating clustered or cooperative kernel nodes is not "
1435 "supported")
1436 arg_holder = ParamHolder(args) 1qvwxrA
1438 c_memset(¶ms, 0, sizeof(params)) 1qvwxrA
1439 params.type = cydriver.CU_GRAPH_NODE_TYPE_KERNEL 1qvwxrA
1440 params.kernel.kern = as_cu(c_kernel._h_kernel) 1qvwxrA
1441 params.kernel.func = <cydriver.CUfunction>NULL 1qvwxrA
1442 params.kernel.gridDimX = c_config.grid[0] 1qvwxrA
1443 params.kernel.gridDimY = c_config.grid[1] 1qvwxrA
1444 params.kernel.gridDimZ = c_config.grid[2] 1qvwxrA
1445 params.kernel.blockDimX = c_config.block[0] 1qvwxrA
1446 params.kernel.blockDimY = c_config.block[1] 1qvwxrA
1447 params.kernel.blockDimZ = c_config.block[2] 1qvwxrA
1448 params.kernel.sharedMemBytes = c_config.shmem_size 1qvwxrA
1449 params.kernel.kernelParams = <void**><uintptr_t>arg_holder.ptr 1qvwxrA
1450 params.kernel.extra = NULL 1qvwxrA
1451 params.kernel.ctx = <cydriver.CUcontext>NULL 1qvwxrA
1453 kernel_args = arg_holder.kernel_args 1qvwxrA
1454 if kernel_args is not None: 1qvwxrA
1455 args_owner = make_opaque_py(kernel_args) 1qvwrA
1456 _set_executable_node_params( 1qvwxrA
1457 self._h_graph_exec, self._h_node, ¶ms,
1458 kernel_owner, args_owner)
1460 @property
1461 def is_enabled(self) -> bool:
1462 """Whether this node is enabled in the executable graph."""
1463 return _get_executable_node_enabled( 1Z
1464 self._h_graph_exec, self._h_node) 1Z
1466 def enable(self) -> None:
1467 """Enable this node in the executable graph."""
1468 _set_executable_node_enabled( 1Z
1469 self._h_graph_exec, self._h_node, True)
1471 def disable(self) -> None:
1472 """Disable this node in the executable graph."""
1473 _set_executable_node_enabled( 1Z
1474 self._h_graph_exec, self._h_node, False)
1477cdef class ExecutableMemsetNode(ExecutableGraphNode):
1478 """An executable memset-node view."""
1480 def update(
1481 self,
1482 *,
1483 dst: Buffer | int,
1484 value,
1485 size_t width,
1486 size_t height=1,
1487 size_t pitch=0,
1488 ) -> None:
1489 """Replace all memset parameters for future launches."""
1490 cdef cydriver.CUdeviceptr c_dst
1491 cdef OpaqueHandle dst_owner = _resolve_memcpy_operand( 1yz
1492 dst, None, "dst", &c_dst)
1493 cdef unsigned int c_value
1494 cdef unsigned int element_size
1495 c_value, element_size = _parse_fill_value(value) 1yz
1497 cdef cydriver.CUcontext ctx = NULL 1yz
1498 cdef cydriver.CUgraphNodeParams params
1499 with nogil: 1yz
1500 HANDLE_RETURN(cydriver.cuCtxGetCurrent(&ctx)) 1yz
1502 c_memset(¶ms, 0, sizeof(params)) 1yz
1503 params.type = cydriver.CU_GRAPH_NODE_TYPE_MEMSET 1yz
1504 params.memset.dst = c_dst 1yz
1505 params.memset.value = c_value 1yz
1506 params.memset.elementSize = element_size 1yz
1507 params.memset.width = width 1yz
1508 params.memset.height = height 1yz
1509 params.memset.pitch = pitch 1yz
1510 params.memset.ctx = ctx 1yz
1511 _set_executable_node_params( 1yz
1512 self._h_graph_exec, self._h_node, ¶ms, dst_owner)
1514 @property
1515 def is_enabled(self) -> bool:
1516 """Whether this node is enabled in the executable graph."""
1517 return _get_executable_node_enabled( 1R
1518 self._h_graph_exec, self._h_node) 1R
1520 def enable(self) -> None:
1521 """Enable this node in the executable graph."""
1522 _set_executable_node_enabled( 1R
1523 self._h_graph_exec, self._h_node, True)
1525 def disable(self) -> None:
1526 """Disable this node in the executable graph."""
1527 _set_executable_node_enabled( 1R
1528 self._h_graph_exec, self._h_node, False)
1531cdef class ExecutableMemcpyNode(ExecutableGraphNode):
1532 """An executable memcpy-node view."""
1534 def update(
1535 self,
1536 *,
1537 dst: Buffer | int,
1538 src: Buffer | int,
1539 size_t size,
1540 ) -> None:
1541 """Replace all one-dimensional memcpy parameters for future launches."""
1542 cdef cydriver.CUdeviceptr c_dst
1543 cdef cydriver.CUdeviceptr c_src
1544 cdef OpaqueHandle dst_owner = _resolve_memcpy_operand( 1FGH
1545 dst, None, "dst", &c_dst)
1546 cdef OpaqueHandle src_owner = _resolve_memcpy_operand( 1FGH
1547 src, None, "src", &c_src)
1548 cdef cydriver.CUmemorytype dst_type
1549 cdef cydriver.CUmemorytype src_type
1550 cdef cydriver.CUcontext ctx = NULL 1FGH
1551 cdef cydriver.CUgraphNodeParams params
1553 c_memset(¶ms, 0, sizeof(params)) 1FGH
1554 params.type = cydriver.CU_GRAPH_NODE_TYPE_MEMCPY 1FGH
1555 _init_memcpy_params( 1FGH
1556 c_dst, c_src, size, ¶ms.memcpy.copyParams,
1557 &dst_type, &src_type)
1558 with nogil: 1FGH
1559 HANDLE_RETURN(cydriver.cuCtxGetCurrent(&ctx)) 1FGH
1560 params.memcpy.copyCtx = ctx 1FGH
1561 _set_executable_node_params( 1FGH
1562 self._h_graph_exec, self._h_node, ¶ms,
1563 dst_owner, src_owner)
1565 @property
1566 def is_enabled(self) -> bool:
1567 """Whether this node is enabled in the executable graph."""
1568 return _get_executable_node_enabled( 1Q
1569 self._h_graph_exec, self._h_node) 1Q
1571 def enable(self) -> None:
1572 """Enable this node in the executable graph."""
1573 _set_executable_node_enabled( 1Q
1574 self._h_graph_exec, self._h_node, True)
1576 def disable(self) -> None:
1577 """Disable this node in the executable graph."""
1578 _set_executable_node_enabled( 1Q
1579 self._h_graph_exec, self._h_node, False)
1582cdef class ExecutableChildGraphNode(ExecutableGraphNode):
1583 """An executable child-graph-node view."""
1585 def update(self, child: GraphDefinition) -> None:
1586 """Replace the embedded graph parameters for future launches."""
1587 GD_check_valid(child) 1LB
1588 cdef cydriver.CUgraphNodeParams params
1589 c_memset(¶ms, 0, sizeof(params)) 1LB
1590 params.type = cydriver.CU_GRAPH_NODE_TYPE_GRAPH 1LB
1591 params.graph.graph = as_cu(child._h_graph) 1LB
1592 _set_executable_node_params( 1LB
1593 self._h_graph_exec, self._h_node, ¶ms)
1596cdef class ExecutableEventRecordNode(ExecutableGraphNode):
1597 """An executable event-record-node view."""
1599 def update(self, event: Event) -> None:
1600 """Replace the event recorded by future launches."""
1601 Event_check_open(event) 1J
1602 cdef OpaqueHandle event_owner = event._h_event 1J
1603 cdef cydriver.CUgraphNodeParams params
1604 c_memset(¶ms, 0, sizeof(params)) 1J
1605 params.type = cydriver.CU_GRAPH_NODE_TYPE_EVENT_RECORD 1J
1606 params.eventRecord.event = as_cu(event._h_event) 1J
1607 _set_executable_node_params( 1J
1608 self._h_graph_exec, self._h_node, ¶ms, event_owner)
1611cdef class ExecutableEventWaitNode(ExecutableGraphNode):
1612 """An executable event-wait-node view."""
1614 def update(self, event: Event) -> None:
1615 """Replace the event waited on by future launches."""
1616 Event_check_open(event) 1D
1617 cdef OpaqueHandle event_owner = event._h_event 1D
1618 cdef cydriver.CUgraphNodeParams params
1619 c_memset(¶ms, 0, sizeof(params)) 1D
1620 params.type = cydriver.CU_GRAPH_NODE_TYPE_WAIT_EVENT 1D
1621 params.eventWait.event = as_cu(event._h_event) 1D
1622 _set_executable_node_params( 1D
1623 self._h_graph_exec, self._h_node, ¶ms, event_owner)
1626cdef class ExecutableHostCallbackNode(ExecutableGraphNode):
1627 """An executable host-callback-node view."""
1629 def update(self, fn, *, user_data=None) -> None:
1630 """Replace the callback and user-data binding for future launches.
1632 ``fn`` may be a Python callable, or a ctypes function pointer whose
1633 declared prototype matches ``CUhostFn`` (``void (*)(void*)``); a
1634 mismatched prototype raises ``TypeError``.
1636 .. warning::
1638 Callbacks must not call CUDA API functions. Doing so may deadlock
1639 or corrupt driver state.
1640 """
1641 cdef cydriver.CUhostFn c_fn
1642 cdef void* c_user_data
1643 cdef OpaqueHandle fn_owner
1644 cdef OpaqueHandle data_owner
1645 cdef cydriver.CUgraphNodeParams params
1647 _resolve_host_callback( 1PMNSKTI
1648 fn, user_data, &c_fn, &c_user_data, &fn_owner, &data_owner)
1649 c_memset(¶ms, 0, sizeof(params)) 1PMNSKTI
1650 params.type = cydriver.CU_GRAPH_NODE_TYPE_HOST 1PMNSKTI
1651 params.host.fn = c_fn 1PMNSKTI
1652 params.host.userData = c_user_data 1PMNSKTI
1653 _set_executable_node_params( 1PMNSKTI
1654 self._h_graph_exec, self._h_node, ¶ms,
1655 fn_owner, data_owner)
1658cdef ExecutableGraphNode create_executable_node_view(
1659 const GraphExecHandle& h_exec,
1660 GraphNode node):
1661 cdef type view_type
1662 if isinstance(node, KernelNode): 2L q P ~bacZ Q R rcB J D M N v w x F G H y z dcS K r A T I
1663 view_type = ExecutableKernelNode 2q ~bacZ rcv w x r A
1664 elif isinstance(node, MemsetNode): 2L P Q R B J D M N F G H y z dcS K T I
1665 view_type = ExecutableMemsetNode 1Ryz
1666 elif isinstance(node, MemcpyNode): 2L P Q B J D M N F G H dcS K T I
1667 view_type = ExecutableMemcpyNode 1QFGH
1668 elif isinstance(node, ChildGraphNode): 2L P B J D M N dcS K T I
1669 view_type = ExecutableChildGraphNode 1LB
1670 elif isinstance(node, EventRecordNode): 2P J D M N dcS K T I
1671 view_type = ExecutableEventRecordNode 1J
1672 elif isinstance(node, EventWaitNode): 2P D M N dcS K T I
1673 view_type = ExecutableEventWaitNode 1D
1674 elif isinstance(node, HostCallbackNode): 2P M N dcS K T I
1675 view_type = ExecutableHostCallbackNode 1PMNSKTI
1676 else:
1677 raise TypeError( 2dc
1678 f"{type(node).__name__} does not support executable updates") 2dc
1680 if as_cu(h_exec) == NULL: 2L q P ~bacZ Q R rcB J D M N v w x F G H y z S K r A T I
1681 raise ValueError("executable graph has been closed")
1682 if as_cu(node._h_node) == NULL: 2L q P ~bacZ Q R rcB J D M N v w x F G H y z S K r A T I
1683 raise ValueError("source graph node is no longer valid")
1685 cdef ExecutableGraphNode view = view_type.__new__(view_type) 2L q P ~bacZ Q R rcB J D M N v w x F G H y z S K r A T I
1686 view._h_graph_exec = h_exec 2L q P ~bacZ Q R rcB J D M N v w x F G H y z S K r A T I
1687 view._h_node = node._h_node 2L q P ~bacZ Q R rcB J D M N v w x F G H y z S K r A T I
1688 return view 2L q P ~bacZ Q R rcB J D M N v w x F G H y z S K r A T I