Coverage for cuda/core/graph/_subclasses.pyx: 86.20%
732 statements
« prev ^ index » next coverage.py v7.17.2, created at 2026-11-05 01:11 +0000
« prev ^ index » next coverage.py v7.17.2, created at 2026-11-05 01:11 +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._rt cimport (
33 ContextHandle,
34 create_context_handle_ref,
35 graph_node_set_params,
36)
37from cuda.core._rt cimport (
38 EventHandle,
39 GraphExecHandle,
40 GraphHandle,
41 GraphNodeHandle,
42 KernelHandle,
43 OpaqueHandle,
44 PreparedAttachment,
45 PreparedChildGraphUpdate,
46 PreparedExecAttachment,
47 as_cu,
48 as_intptr,
49 create_child_graph_handle,
50 create_event_handle_ref,
51 create_kernel_handle_ref,
52 graph_commit_attachment,
53 graph_commit_child_graph_update,
54 graph_commit_exec_attachment,
55 graph_get_attachment,
56 graph_node_get_graph,
57 graph_prepare_attachment,
58 graph_prepare_child_graph_update,
59 graph_prepare_exec_attachment,
60 make_opaque_py,
61)
62from cuda.core._utils.cuda_utils cimport HANDLE_RETURN, _parse_fill_value
63from cuda.core._utils.version cimport cy_driver_version
65from cuda.core._host_callback cimport (
66 _is_py_host_trampoline,
67 _resolve_host_callback,
68)
70from cuda.core.typing import GraphConditionalType
72__all__ = [
73 'AllocNode',
74 'ChildGraphNode',
75 'ConditionalNode',
76 'EmptyNode',
77 'EventRecordNode',
78 'EventWaitNode',
79 'ExecutableChildGraphNode',
80 'ExecutableEventRecordNode',
81 'ExecutableEventWaitNode',
82 'ExecutableGraphNode',
83 'ExecutableHostCallbackNode',
84 'ExecutableKernelNode',
85 'ExecutableMemcpyNode',
86 'ExecutableMemsetNode',
87 'FreeNode',
88 'HostCallbackNode',
89 'IfElseNode',
90 'IfNode',
91 'KernelNode',
92 'MemcpyNode',
93 'MemsetNode',
94 'SwitchNode',
95 'WhileNode',
96]
99cdef void _require_graph_node_update_support() except *:
100 cdef tuple version = cy_driver_version() 1LNUz1;)*+qpohlimnV~}Mu3WXK4RSTBCDGHIEFY:=?OA]jkabdefgJZ0c
101 if version < (12, 2, 0): 1LNUz1;)*+qpohlimnV~}Mu3WXK4RSTBCDGHIEFY:=?OA]jkabdefgJZ0c
102 raise RuntimeError(
103 "Graph node mutation requires CUDA driver 12.2 or newer; "
104 f"using driver version {'.'.join(map(str, version))}"
105 )
108cdef void _set_definition_node_params(
109 const GraphNodeHandle& h_node,
110 cydriver.CUgraphNodeParams* params,
111 OpaqueHandle owner0,
112 OpaqueHandle owner1=OpaqueHandle(),
113 cydriver.CUcontext update_ctx=NULL) except *:
114 cdef GraphHandle h_graph = graph_node_get_graph(h_node) 1;)*+qpohlimnjkabdefgc
115 cdef cydriver.CUgraphNode node = as_cu(h_node) 1;)*+qpohlimnjkabdefgc
116 if as_cu(h_graph) == NULL: 1;)*+qpohlimnjkabdefgc
117 raise RuntimeError("GraphDefinition is no longer valid")
118 if node == NULL: 1;)*+qpohlimnjkabdefgc
119 raise RuntimeError("GraphNode has been destroyed")
120 _require_graph_node_update_support() 1;)*+qpohlimnjkabdefgc
121 cdef PreparedAttachment prepared
122 cdef ContextHandle h_update_ctx
123 cdef cydriver.CUresult status
124 cdef cydriver.CUresult restore_status = cydriver.CUresult.CUDA_SUCCESS 1;)*+qpohlimnjkabdefgc
126 HANDLE_RETURN(graph_prepare_attachment( 1;)*+qpohlimnjkabdefgc
127 h_graph, owner0, owner1, &prepared))
128 if update_ctx != NULL: 1;)*+qpohlimnjkabdefgc
129 h_update_ctx = create_context_handle_ref(update_ctx) 1hlimnjkabdefgc
130 with nogil: 1;)*+qpohlimnjkabdefgc
131 status = graph_node_set_params(node, params, h_update_ctx, &restore_status) 1;)*+qpohlimnjkabdefgc
132 HANDLE_RETURN(status) 1;)*+qpohlimnjkabdefgc
133 # The driver node now references the new owners. Publish their attachment
134 # before raising anything else: an exception here would roll back the
135 # prepared retention and leave the node pointing at released resources.
136 try: 1;)*+qpohlimnjkabdefgc
137 HANDLE_RETURN(graph_commit_attachment(prepared, node)) 1;)*+qpohlimnjkabdefgc
138 finally:
139 HANDLE_RETURN(restore_status) 1;)*+qpohlimnjkabdefgc
142cdef void _set_executable_node_params(
143 const GraphExecHandle& h_exec,
144 const GraphNodeHandle& h_node,
145 cydriver.CUgraphNodeParams* params,
146 OpaqueHandle owner0=OpaqueHandle(),
147 OpaqueHandle owner1=OpaqueHandle()) except *:
148 _require_graph_node_update_support() 1UzVMuK4RSTBCDGHIEFYOAabJZ0
150 cdef cydriver.CUgraphExec graph_exec = as_cu(h_exec) 1UzVMuK4RSTBCDGHIEFYOAabJZ0
151 cdef cydriver.CUgraphNode node = as_cu(h_node) 1UzVMuK4RSTBCDGHIEFYOAabJZ0
152 if graph_exec == NULL: 1UzVMuK4RSTBCDGHIEFYOAabJZ0
153 raise RuntimeError("Graph has been closed")
154 if node == NULL: 1UzVMuK4RSTBCDGHIEFYOAabJZ0
155 raise RuntimeError("GraphNode has been destroyed") 1M
157 cdef PreparedExecAttachment prepared
158 HANDLE_RETURN(graph_prepare_exec_attachment( 1UzVuK4RSTBCDGHIEFYOAabJZ0
159 h_exec, owner0, owner1, &prepared))
161 cdef cydriver.CUresult status
162 with nogil: 1UzVuK4RSTBCDGHIEFYOAabJZ0
163 status = cydriver.cuGraphExecNodeSetParams( 1UzVuK4RSTBCDGHIEFYOAabJZ0
164 graph_exec, node, params)
165 if status == cydriver.CUDA_SUCCESS: 1UzVuK4RSTBCDGHIEFYOAabJZ0
166 graph_commit_exec_attachment(prepared) 1UzVuK4RSTBCDGHIEFYOAaZ0
167 HANDLE_RETURN(status) 1UzVuK4RSTBCDGHIEFYOAabJZ0
170cdef bint _get_executable_node_enabled(
171 const GraphExecHandle& h_exec,
172 const GraphNodeHandle& h_node) except *:
173 _require_graph_node_update_support() 1}3WX
175 cdef cydriver.CUgraphExec graph_exec = as_cu(h_exec) 1}3WX
176 cdef cydriver.CUgraphNode node = as_cu(h_node) 1}3WX
177 cdef unsigned int enabled
178 if graph_exec == NULL: 1}3WX
179 raise RuntimeError("Graph has been closed")
180 if node == NULL: 1}3WX
181 raise RuntimeError("GraphNode has been destroyed") 1}
182 with nogil: 13WX
183 HANDLE_RETURN(cydriver.cuGraphNodeGetEnabled( 13WX
184 graph_exec, node, &enabled))
185 return enabled != 0 13WX
188cdef void _set_executable_node_enabled(
189 const GraphExecHandle& h_exec,
190 const GraphNodeHandle& h_node,
191 bint enabled) except *:
192 _require_graph_node_update_support() 1~3WX
194 cdef cydriver.CUgraphExec graph_exec = as_cu(h_exec) 1~3WX
195 cdef cydriver.CUgraphNode node = as_cu(h_node) 1~3WX
196 if graph_exec == NULL: 1~3WX
197 raise RuntimeError("Graph has been closed")
198 if node == NULL: 1~3WX
199 raise RuntimeError("GraphNode has been destroyed") 1~
200 with nogil: 13WX
201 HANDLE_RETURN(cydriver.cuGraphNodeSetEnabled( 13WX
202 graph_exec, node, <unsigned int>enabled))
205cdef bint _check_node_get_params():
206 """Whether cuGraphNodeGetParams, a 13.2 driver API, is available.
208 The CUDA 13 build always has the binding. Only the driver can lack it."""
209 IF CUDA_CORE_BUILD_MAJOR >= 13:
210 return cy_driver_version() >= (13, 2, 0) 1859!#6$%@hlimnvwx'(rstPQjkabdef2gc
211 ELSE:
212 return False
215IF CUDA_CORE_BUILD_MAJOR >= 13:
216 cdef void _node_get_params(
217 cydriver.CUgraphNode node,
218 cydriver.CUgraphNodeParams* params) except *:
219 c_memset(params, 0, sizeof(params[0])) 1859!#6$%@hlimnvwx'(rstPQjkabdef2gc
220 with nogil: 1859!#6$%@hlimnvwx'(rstPQjkabdef2gc
221 HANDLE_RETURN(cydriver.cuGraphNodeGetParams(node, params)) 1859!#6$%@hlimnvwx'(rstPQjkabdef2gc
224cdef void _reject_unsupported_kernel_node(
225 cydriver.CUgraphNode node) except *:
226 cdef cydriver.CUkernelNodeAttrValue cluster
227 cdef cydriver.CUkernelNodeAttrValue cooperative
229 c_memset(&cluster, 0, sizeof(cluster)) 1qpo=?]
230 c_memset(&cooperative, 0, sizeof(cooperative)) 1qpo=?]
231 with nogil: 1qpo=?]
232 HANDLE_RETURN(cydriver.cuGraphKernelNodeGetAttribute( 1qpo=?]
233 node, <cydriver.CUkernelNodeAttrID>(
234 cydriver.CU_KERNEL_NODE_ATTRIBUTE_CLUSTER_DIMENSION),
235 &cluster))
236 HANDLE_RETURN(cydriver.cuGraphKernelNodeGetAttribute( 1qpo=?]
237 node, <cydriver.CUkernelNodeAttrID>(
238 cydriver.CU_KERNEL_NODE_ATTRIBUTE_COOPERATIVE),
239 &cooperative))
240 if (cluster.clusterDim.x != 0 or cluster.clusterDim.y != 0 or 1qpo=?]
241 cluster.clusterDim.z != 0 or cooperative.cooperative != 0): 1qpo=?]
242 raise NotImplementedError( 1]
243 "updating clustered or cooperative kernel nodes is not supported")
246cdef inline bint _is_linear_memcpy_memory_type(
247 cydriver.CUmemorytype memory_type) noexcept nogil:
248 # HOST and DEVICE name the location of a linear operand. UNIFIED is what
249 # the driver records for a copy captured from cuMemcpyAsync: a generic
250 # address that it resolves itself, stored in the device-pointer field.
251 return (memory_type == cydriver.CU_MEMORYTYPE_HOST 1hlivwxrstjk2c
252 or memory_type == cydriver.CU_MEMORYTYPE_DEVICE 1hlivwxrstjkabdef2c
253 or memory_type == cydriver.CU_MEMORYTYPE_UNIFIED) 1hlivwxrstjkabdef2c
256cdef str _memcpy_memory_type_tag(cydriver.CUmemorytype memory_type):
257 if memory_type == cydriver.CU_MEMORYTYPE_HOST: 2f 0e
258 return "H"
259 if memory_type == cydriver.CU_MEMORYTYPE_DEVICE: 2f 0e
260 return "D" 20e
261 if memory_type == cydriver.CU_MEMORYTYPE_UNIFIED: 1f
262 return "U" 1f
263 if memory_type == cydriver.CU_MEMORYTYPE_ARRAY:
264 return "A"
265 return str(int(memory_type))
268cdef bint _is_supported_memcpy_descriptor(
269 cydriver.CUDA_MEMCPY3D* params) noexcept nogil:
270 return (
271 _is_linear_memcpy_memory_type(params.srcMemoryType) 1hlivwxrstjkabdef2c
272 and _is_linear_memcpy_memory_type(params.dstMemoryType) 1hlivwxrstjkabdef2c
273 and params.srcXInBytes == 0 1hlivwxrstjkabdef2c
274 and params.srcY == 0 1hlivwxrstjkabdefc
275 and params.srcZ == 0 1hlivwxrstjkabdefc
276 and params.srcLOD == 0 1hlivwxrstjkabdefc
277 and params.srcPitch == 0 1hlivwxrstjkabdefc
278 and params.srcHeight == 0 1hlivwxrstjkabdefc
279 and params.dstXInBytes == 0 1hlivwxrstjkabdefc
280 and params.dstY == 0 1hlivwxrstjkabdefc
281 and params.dstZ == 0 1hlivwxrstjkabdefc
282 and params.dstLOD == 0 1hlivwxrstjkabdefc
283 and params.dstPitch == 0 1hlivwxrstjkabdefc
284 and params.dstHeight == 0 1hlivwxrstjkabdefc
285 and params.Height == 1 1hlivwxrstjkabdefc
286 and params.Depth == 1 1hlivwxrstjkabdefc
287 and params.reserved0 == NULL 1hlivwxrstjkabdefc
288 and params.reserved1 == NULL 1hlivwxrstjkabdefc
289 )
292cdef class EmptyNode(GraphNode):
293 """An empty (synchronization) node."""
295 @staticmethod
296 cdef EmptyNode _create_impl(GraphNodeHandle h_node):
297 cdef EmptyNode n = EmptyNode.__new__(EmptyNode) 2]f^f[c]c_f, - . / ^c_c`c`f{f|f{csb|cabtb}c~cadbdcdubddrbvbed}fwbfdxbgdhdidjd~fkdldag5dbgmdcgdg7 VdWdXdYdZdeg3ffggghg0digjgkgLbO 6d7dndyb4fodzbpdAby qdBbrdCbsdDbtdEbudFbvdGbwdHbxdIb
298 n._h_node = h_node 2]f^f[c]c_f, - . / ^c_c`c`f{f|f{csb|cabtb}c~cadbdcdubddrbvbed}fwbfdxbgdhdidjd~fkdldag5dbgmdcgdg7 VdWdXdYdZdeg3ffggghg0digjgkgLbO 6d7dndyb4fodzbpdAby qdBbrdCbsdDbtdEbudFbvdGbwdHbxdIb
299 return n 2]f^f[c]c_f, - . / ^c_c`c`f{f|f{csb|cabtb}c~cadbdcdubddrbvbed}fwbfdxbgdhdidjd~fkdldag5dbgmdcgdg7 VdWdXdYdZdeg3ffggghg0digjgkgLbO 6d7dndyb4fodzbpdAby qdBbrdCbsdDbtdEbudFbvdGbwdHbxdIb
301 def __repr__(self) -> str:
302 return f"<EmptyNode handle=0x{as_intptr(self._h_node):x}>" 23f4fxg
305cdef class KernelNode(GraphNode):
306 """A kernel launch node.
308 Properties
309 ----------
310 grid : tuple of int
311 Grid dimensions (gridDimX, gridDimY, gridDimZ).
312 block : tuple of int
313 Block dimensions (blockDimX, blockDimY, blockDimZ).
314 shmem_size : int
315 Dynamic shared memory size in bytes.
316 kernel : Kernel
317 The kernel object for this launch node.
318 config : LaunchConfig
319 A LaunchConfig reconstructed from this node's parameters.
320 """
322 @staticmethod
323 cdef KernelNode _create_with_params(GraphNodeHandle h_node,
324 tuple grid, tuple block, unsigned int shmem_size,
325 KernelHandle h_kernel):
326 """Create from known params (called by launch() builder)."""
327 cdef KernelNode n = KernelNode.__new__(KernelNode) 2Bc1eCcDcEcyd2e3e4e5e6e7e8erczdscAdtcBducCdvcDdwcEdxc9e!eycoczcAcMb#e$e)d%c%e'e^ VdWdXdYdZd[ z q p o LcMcNc*d+d,d~ } M JbKb3 SbB C D Lb= pc? A ] qcJ (eFd)eGd*eHd+ey Id,eJd-eKd.eLd/eMd:eNd;eOd=ePd?e
328 n._h_node = h_node 2Bc1eCcDcEcyd2e3e4e5e6e7e8erczdscAdtcBducCdvcDdwcEdxc9e!eycoczcAcMb#e$e)d%c%e'e^ VdWdXdYdZd[ z q p o LcMcNc*d+d,d~ } M JbKb3 SbB C D Lb= pc? A ] qcJ (eFd)eGd*eHd+ey Id,eJd-eKd.eLd/eMd:eNd;eOd=ePd?e
329 n._grid = grid 2Bc1eCcDcEcyd2e3e4e5e6e7e8erczdscAdtcBducCdvcDdwcEdxc9e!eycoczcAcMb#e$e)d%c%e'e^ VdWdXdYdZd[ z q p o LcMcNc*d+d,d~ } M JbKb3 SbB C D Lb= pc? A ] qcJ (eFd)eGd*eHd+ey Id,eJd-eKd.eLd/eMd:eNd;eOd=ePd?e
330 n._block = block 2Bc1eCcDcEcyd2e3e4e5e6e7e8erczdscAdtcBducCdvcDdwcEdxc9e!eycoczcAcMb#e$e)d%c%e'e^ VdWdXdYdZd[ z q p o LcMcNc*d+d,d~ } M JbKb3 SbB C D Lb= pc? A ] qcJ (eFd)eGd*eHd+ey Id,eJd-eKd.eLd/eMd:eNd;eOd=ePd?e
331 n._shmem_size = shmem_size 2Bc1eCcDcEcyd2e3e4e5e6e7e8erczdscAdtcBducCdvcDdwcEdxc9e!eycoczcAcMb#e$e)d%c%e'e^ VdWdXdYdZd[ z q p o LcMcNc*d+d,d~ } M JbKb3 SbB C D Lb= pc? A ] qcJ (eFd)eGd*eHd+ey Id,eJd-eKd.eLd/eMd:eNd;eOd=ePd?e
332 n._h_kernel = h_kernel 2Bc1eCcDcEcyd2e3e4e5e6e7e8erczdscAdtcBducCdvcDdwcEdxc9e!eycoczcAcMb#e$e)d%c%e'e^ VdWdXdYdZd[ z q p o LcMcNc*d+d,d~ } M JbKb3 SbB C D Lb= pc? A ] qcJ (eFd)eGd*eHd+ey Id,eJd-eKd.eLd/eMd:eNd;eOd=ePd?e
333 return n 2Bc1eCcDcEcyd2e3e4e5e6e7e8erczdscAdtcBducCdvcDdwcEdxc9e!eycoczcAcMb#e$e)d%c%e'e^ VdWdXdYdZd[ z q p o LcMcNc*d+d,d~ } M JbKb3 SbB C D Lb= pc? A ] qcJ (eFd)eGd*eHd+ey Id,eJd-eKd.eLd/eMd:eNd;eOd=ePd?e
335 @staticmethod
336 cdef KernelNode _create_from_driver(GraphNodeHandle h_node):
337 """Create by fetching params from the driver (called by _create factory)."""
338 cdef cydriver.CUgraphNode node = as_cu(h_node) 2BcCcDcEcrcycoczcAcMb^ [
339 cdef cydriver.CUDA_KERNEL_NODE_PARAMS params
340 with nogil: 2BcCcDcEcrcycoczcAcMb^ [
341 HANDLE_RETURN(cydriver.cuGraphKernelNodeGetParams(node, ¶ms)) 2BcCcDcEcrcycoczcAcMb^ [
342 cdef KernelHandle h_kernel = create_kernel_handle_ref(params.kern) 2BcCcDcEcrcycoczcAcMb^ [
343 return KernelNode._create_with_params( 2BcCcDcEcrcycoczcAcMb^ [
344 h_node,
345 (params.gridDimX, params.gridDimY, params.gridDimZ), 2BcCcDcEcrcycoczcAcMb^ [
346 (params.blockDimX, params.blockDimY, params.blockDimZ), 2BcCcDcEcrcycoczcAcMb^ [
347 params.sharedMemBytes,
348 h_kernel)
350 def __repr__(self) -> str:
351 return (f"<KernelNode handle=0x{as_intptr(self._h_node):x}" 2mg
352 f" kernel=0x{as_intptr(self._h_kernel):x}>") 2mg
354 def update(
355 self,
356 *,
357 config: LaunchConfig | None = None,
358 kernel: Kernel | None = None,
359 args=None,
360 ) -> None:
361 """Replace selected kernel launch parameters.
363 Omitted parameters preserve their current values. Changing ``kernel``
364 requires ``args``, including ``args=()`` for a no-argument kernel.
365 Clustered and cooperative kernel nodes are not supported.
367 .. warning::
369 Use caution when a retained kernel argument directly or indirectly
370 owns a graph. Any reference cycle involving the argument and a
371 graph that retains it cannot be broken by Python's cyclic garbage
372 collector. Use a weak reference to break such cycles.
373 """
374 GN_check_valid(self) 2q p o LcMcNc*d+d,d= pc? ] qc
375 cdef LaunchConfig c_config
376 cdef Kernel c_kernel
377 cdef ParamHolder arg_holder
378 cdef object kernel_args
379 cdef KernelHandle h_kernel = self._h_kernel 2q p o LcMcNc= pc? ] qc
380 cdef OpaqueHandle kernel_owner
381 cdef OpaqueHandle args_owner
382 cdef GraphHandle h_graph = graph_node_get_graph(self._h_node) 2q p o LcMcNc= pc? ] qc
383 cdef cydriver.CUgraphNode node = as_cu(self._h_node) 2q p o LcMcNc= pc? ] qc
384 cdef cydriver.CUgraphNodeParams params
386 if config is not None: 2q p o LcMcNc= pc? ] qc
387 c_config = config 2p LcMcNcpc] qc
388 if (c_config.cluster is not None or 2p ] qc
389 c_config.is_cooperative): 2p ] qc
390 raise NotImplementedError( 2qc
391 "updating clustered or cooperative kernel nodes is not "
392 "supported")
393 _require_graph_node_update_support() 1qpo=?]
394 _reject_unsupported_kernel_node(node) 1qpo=?]
395 if kernel is not None: 1qpo=?
396 if args is None: 1o?
397 raise ValueError("changing kernel requires args") 1?
398 c_kernel = kernel 1o
399 h_kernel = c_kernel._h_kernel 1o
400 if args is not None: 1qpo=
401 arg_holder = ParamHolder(args) 1qo=
403 c_memset(¶ms, 0, sizeof(params)) 1qpo
404 params.type = cydriver.CU_GRAPH_NODE_TYPE_KERNEL 1qpo
405 with nogil: 1qpo
406 HANDLE_RETURN(cydriver.cuGraphKernelNodeGetParams( 1qpo
407 node, <cydriver.CUDA_KERNEL_NODE_PARAMS*>¶ms.kernel))
408 HANDLE_RETURN(graph_get_attachment( 1qpo
409 h_graph, node, &kernel_owner, &args_owner))
411 if config is not None: 1qpo
412 params.kernel.gridDimX = c_config.grid[0] 1p
413 params.kernel.gridDimY = c_config.grid[1] 1p
414 params.kernel.gridDimZ = c_config.grid[2] 1p
415 params.kernel.blockDimX = c_config.block[0] 1p
416 params.kernel.blockDimY = c_config.block[1] 1p
417 params.kernel.blockDimZ = c_config.block[2] 1p
418 params.kernel.sharedMemBytes = c_config.shmem_size 1p
419 if kernel is not None: 1qpo
420 params.kernel.kern = as_cu(h_kernel) 1o
421 params.kernel.func = <cydriver.CUfunction>NULL 1o
422 params.kernel.ctx = <cydriver.CUcontext>NULL 1o
423 kernel_owner = h_kernel 1o
424 if args is not None: 1qpo
425 params.kernel.kernelParams = <void**><uintptr_t>arg_holder.ptr 1qo
426 params.kernel.extra = NULL 1qo
427 kernel_args = arg_holder.kernel_args 1qo
428 if kernel_args is None: 1qo
429 args_owner = OpaqueHandle() 1o
430 else:
431 args_owner = make_opaque_py(kernel_args) 1q
433 _set_definition_node_params( 1qpo
434 self._h_node, ¶ms, kernel_owner, args_owner)
435 self._grid = ( 1qpo
436 params.kernel.gridDimX, 1qpo
437 params.kernel.gridDimY, 1qpo
438 params.kernel.gridDimZ, 1qpo
439 )
440 self._block = ( 1qpo
441 params.kernel.blockDimX, 1qpo
442 params.kernel.blockDimY, 1qpo
443 params.kernel.blockDimZ, 1qpo
444 )
445 self._shmem_size = params.kernel.sharedMemBytes 1qpo
446 self._h_kernel = h_kernel 1qpo
448 @property
449 def grid(self) -> tuple[int, int, int]:
450 """Grid dimensions as a 3-tuple (gridDimX, gridDimY, gridDimZ)."""
451 return self._grid 2`ebb
453 @property
454 def block(self) -> tuple[int, int, int]:
455 """Block dimensions as a 3-tuple (blockDimX, blockDimY, blockDimZ)."""
456 return self._block 2`ebb
458 @property
459 def shmem_size(self) -> int:
460 """Dynamic shared memory size in bytes."""
461 return self._shmem_size 2`ebb
463 @property
464 def kernel(self) -> Kernel:
465 """The Kernel object for this launch node."""
466 return Kernel._from_handle(self._h_kernel) 2`ebb)d%cq p o B C D = pc?
468 @property
469 def config(self) -> LaunchConfig:
470 """A LaunchConfig reconstructed from this node's grid, block, and shmem_size.
472 Note: cluster dimensions and is_cooperative are not preserved
473 by the CUDA driver's kernel node params, so they are not included.
474 """
475 return LaunchConfig(grid=self._grid, block=self._block, 2`ebbq p o B C D = pc?
476 shmem_size=self._shmem_size) 2`ebbq p o B C D = pc?
479cdef class AllocNode(GraphNode):
480 """A memory allocation node.
482 Properties
483 ----------
484 dptr : int
485 The device pointer for the allocation.
486 bytesize : int
487 The number of bytes allocated.
488 device_id : int
489 The device on which the allocation was made.
490 memory_type : GraphMemoryType | str
491 The type of memory allocated.
492 peer_access : tuple of int
493 Device IDs that have read-write access to this allocation.
494 """
496 @staticmethod
497 cdef AllocNode _create_with_params(GraphNodeHandle h_node,
498 cydriver.CUdeviceptr dptr, size_t bytesize,
499 int device_id, str memory_type, tuple peer_access):
500 """Create from known params (called by allocate() builder)."""
501 cdef AllocNode n = AllocNode.__new__(AllocNode) 28d9dOc-d.d/d:d[c;d]c=d?dPcQcRcScTc, - . / mbnbobpb@d[d]d^c_c`c^d_d{c'c(cUcscsbTbUbVbWbjb`dkb{d|cNb)cOb*cPbVcbbtcabtbcbXbdbYbebZbfb0b|d}c}d~c~daebeadcebddeeefegecd+c,cWcucub1b2b3b4b5bhe6bie7bdd8b-c9b.c!bXc#bvcrbvb$b%b'b(b)b*b+b,b-bje.bke/bed:b/c;b:c=bYc?bwcwb@b[b]b^b_b`b{b|blemefd;c=cZcxcxb}b~bacbcnegdoehdpeqereidsejdteuevekdweldxeyemd!dze0c1cgbhbqb7 FcAend2cybccBeod3czbdcCepd4cAbecy Deqd5cBbfcEerd6cCbgcFesd7cDbhcGetd8cEbicHeud9cFbjcIevd!cGbkcJewd#cHblcKexd$cIbmc
502 n._h_node = h_node 28d9dOc-d.d/d:d[c;d]c=d?dPcQcRcScTc, - . / mbnbobpb@d[d]d^c_c`c^d_d{c'c(cUcscsbTbUbVbWbjb`dkb{d|cNb)cOb*cPbVcbbtcabtbcbXbdbYbebZbfb0b|d}c}d~c~daebeadcebddeeefegecd+c,cWcucub1b2b3b4b5bhe6bie7bdd8b-c9b.c!bXc#bvcrbvb$b%b'b(b)b*b+b,b-bje.bke/bed:b/c;b:c=bYc?bwcwb@b[b]b^b_b`b{b|blemefd;c=cZcxcxb}b~bacbcnegdoehdpeqereidsejdteuevekdweldxeyemd!dze0c1cgbhbqb7 FcAend2cybccBeod3czbdcCepd4cAbecy Deqd5cBbfcEerd6cCbgcFesd7cDbhcGetd8cEbicHeud9cFbjcIevd!cGbkcJewd#cHblcKexd$cIbmc
503 n._dptr = dptr 28d9dOc-d.d/d:d[c;d]c=d?dPcQcRcScTc, - . / mbnbobpb@d[d]d^c_c`c^d_d{c'c(cUcscsbTbUbVbWbjb`dkb{d|cNb)cOb*cPbVcbbtcabtbcbXbdbYbebZbfb0b|d}c}d~c~daebeadcebddeeefegecd+c,cWcucub1b2b3b4b5bhe6bie7bdd8b-c9b.c!bXc#bvcrbvb$b%b'b(b)b*b+b,b-bje.bke/bed:b/c;b:c=bYc?bwcwb@b[b]b^b_b`b{b|blemefd;c=cZcxcxb}b~bacbcnegdoehdpeqereidsejdteuevekdweldxeyemd!dze0c1cgbhbqb7 FcAend2cybccBeod3czbdcCepd4cAbecy Deqd5cBbfcEerd6cCbgcFesd7cDbhcGetd8cEbicHeud9cFbjcIevd!cGbkcJewd#cHblcKexd$cIbmc
504 n._bytesize = bytesize 28d9dOc-d.d/d:d[c;d]c=d?dPcQcRcScTc, - . / mbnbobpb@d[d]d^c_c`c^d_d{c'c(cUcscsbTbUbVbWbjb`dkb{d|cNb)cOb*cPbVcbbtcabtbcbXbdbYbebZbfb0b|d}c}d~c~daebeadcebddeeefegecd+c,cWcucub1b2b3b4b5bhe6bie7bdd8b-c9b.c!bXc#bvcrbvb$b%b'b(b)b*b+b,b-bje.bke/bed:b/c;b:c=bYc?bwcwb@b[b]b^b_b`b{b|blemefd;c=cZcxcxb}b~bacbcnegdoehdpeqereidsejdteuevekdweldxeyemd!dze0c1cgbhbqb7 FcAend2cybccBeod3czbdcCepd4cAbecy Deqd5cBbfcEerd6cCbgcFesd7cDbhcGetd8cEbicHeud9cFbjcIevd!cGbkcJewd#cHblcKexd$cIbmc
505 n._device_id = device_id 28d9dOc-d.d/d:d[c;d]c=d?dPcQcRcScTc, - . / mbnbobpb@d[d]d^c_c`c^d_d{c'c(cUcscsbTbUbVbWbjb`dkb{d|cNb)cOb*cPbVcbbtcabtbcbXbdbYbebZbfb0b|d}c}d~c~daebeadcebddeeefegecd+c,cWcucub1b2b3b4b5bhe6bie7bdd8b-c9b.c!bXc#bvcrbvb$b%b'b(b)b*b+b,b-bje.bke/bed:b/c;b:c=bYc?bwcwb@b[b]b^b_b`b{b|blemefd;c=cZcxcxb}b~bacbcnegdoehdpeqereidsejdteuevekdweldxeyemd!dze0c1cgbhbqb7 FcAend2cybccBeod3czbdcCepd4cAbecy Deqd5cBbfcEerd6cCbgcFesd7cDbhcGetd8cEbicHeud9cFbjcIevd!cGbkcJewd#cHblcKexd$cIbmc
506 n._memory_type = memory_type 28d9dOc-d.d/d:d[c;d]c=d?dPcQcRcScTc, - . / mbnbobpb@d[d]d^c_c`c^d_d{c'c(cUcscsbTbUbVbWbjb`dkb{d|cNb)cOb*cPbVcbbtcabtbcbXbdbYbebZbfb0b|d}c}d~c~daebeadcebddeeefegecd+c,cWcucub1b2b3b4b5bhe6bie7bdd8b-c9b.c!bXc#bvcrbvb$b%b'b(b)b*b+b,b-bje.bke/bed:b/c;b:c=bYc?bwcwb@b[b]b^b_b`b{b|blemefd;c=cZcxcxb}b~bacbcnegdoehdpeqereidsejdteuevekdweldxeyemd!dze0c1cgbhbqb7 FcAend2cybccBeod3czbdcCepd4cAbecy Deqd5cBbfcEerd6cCbgcFesd7cDbhcGetd8cEbicHeud9cFbjcIevd!cGbkcJewd#cHblcKexd$cIbmc
507 n._peer_access = peer_access 28d9dOc-d.d/d:d[c;d]c=d?dPcQcRcScTc, - . / mbnbobpb@d[d]d^c_c`c^d_d{c'c(cUcscsbTbUbVbWbjb`dkb{d|cNb)cOb*cPbVcbbtcabtbcbXbdbYbebZbfb0b|d}c}d~c~daebeadcebddeeefegecd+c,cWcucub1b2b3b4b5bhe6bie7bdd8b-c9b.c!bXc#bvcrbvb$b%b'b(b)b*b+b,b-bje.bke/bed:b/c;b:c=bYc?bwcwb@b[b]b^b_b`b{b|blemefd;c=cZcxcxb}b~bacbcnegdoehdpeqereidsejdteuevekdweldxeyemd!dze0c1cgbhbqb7 FcAend2cybccBeod3czbdcCepd4cAbecy Deqd5cBbfcEerd6cCbgcFesd7cDbhcGetd8cEbicHeud9cFbjcIevd!cGbkcJewd#cHblcKexd$cIbmc
508 return n 28d9dOc-d.d/d:d[c;d]c=d?dPcQcRcScTc, - . / mbnbobpb@d[d]d^c_c`c^d_d{c'c(cUcscsbTbUbVbWbjb`dkb{d|cNb)cOb*cPbVcbbtcabtbcbXbdbYbebZbfb0b|d}c}d~c~daebeadcebddeeefegecd+c,cWcucub1b2b3b4b5bhe6bie7bdd8b-c9b.c!bXc#bvcrbvb$b%b'b(b)b*b+b,b-bje.bke/bed:b/c;b:c=bYc?bwcwb@b[b]b^b_b`b{b|blemefd;c=cZcxcxb}b~bacbcnegdoehdpeqereidsejdteuevekdweldxeyemd!dze0c1cgbhbqb7 FcAend2cybccBeod3czbdcCepd4cAbecy Deqd5cBbfcEerd6cCbgcFesd7cDbhcGetd8cEbicHeud9cFbjcIevd!cGbkcJewd#cHblcKexd$cIbmc
510 @staticmethod
511 cdef AllocNode _create_from_driver(GraphNodeHandle h_node):
512 """Create by fetching params from the driver (called by _create factory)."""
513 cdef cydriver.CUgraphNode node = as_cu(h_node) 2jbkbNbObPbbbabcbdbebfb5b6b7b8b9b!b#brb$b'b)b+b-b.b/b:b;b=b?b@b]b_b{bgbhb
514 cdef cydriver.CUDA_MEM_ALLOC_NODE_PARAMS params
515 with nogil: 2jbkbNbObPbbbabcbdbebfb5b6b7b8b9b!b#brb$b'b)b+b-b.b/b:b;b=b?b@b]b_b{bgbhb
516 HANDLE_RETURN(cydriver.cuGraphMemAllocNodeGetParams(node, ¶ms)) 2jbkbNbObPbbbabcbdbebfb5b6b7b8b9b!b#brb$b'b)b+b-b.b/b:b;b=b?b@b]b_b{bgbhb
518 cdef str memory_type
519 if params.poolProps.allocType == cydriver.CUmemAllocationType.CU_MEM_ALLOCATION_TYPE_PINNED: 2jbkbNbObPbbbabcbdbebfb5b6b7b8b9b!b#brb$b'b)b+b-b.b/b:b;b=b?b@b]b_b{bgbhb
520 if params.poolProps.location.type == cydriver.CUmemLocationType.CU_MEM_LOCATION_TYPE_HOST: 2jbkbNbObPbbbabcbdbebfb5b6b7b8b9b!b#brb$b'b)b+b-b.b/b:b;b=b?b@b]b_b{bhb
521 memory_type = "host"
522 else:
523 memory_type = "device" 2jbkbNbObPbbbabcbdbebfb5b6b7b8b9b!b#brb$b'b)b+b-b.b/b:b;b=b?b@b]b_b{bhb
524 else:
525 IF CUDA_CORE_BUILD_MAJOR >= 13:
526 if params.poolProps.allocType == cydriver.CUmemAllocationType.CU_MEM_ALLOCATION_TYPE_MANAGED: 2gb
527 memory_type = "managed" 2gb
528 else:
529 memory_type = "device"
530 ELSE:
531 memory_type = "device"
533 cdef list peer_ids = [] 2jbkbNbObPbbbabcbdbebfb5b6b7b8b9b!b#brb$b'b)b+b-b.b/b:b;b=b?b@b]b_b{bgbhb
534 cdef size_t i
535 for i in range(params.accessDescCount): 2jbkbNbObPbbbabcbdbebfb5b6b7b8b9b!b#brb$b'b)b+b-b.b/b:b;b=b?b@b]b_b{bgbhb
536 peer_ids.append(<int>params.accessDescs[i].location.id) 2hb
538 return AllocNode._create_with_params( 2jbkbNbObPbbbabcbdbebfb5b6b7b8b9b!b#brb$b'b)b+b-b.b/b:b;b=b?b@b]b_b{bgbhb
539 h_node, params.dptr, params.bytesize,
540 <int>params.poolProps.location.id, memory_type, tuple(peer_ids)) 2jbkbNbObPbbbabcbdbebfb5b6b7b8b9b!b#brb$b'b)b+b-b.b/b:b;b=b?b@b]b_b{bgbhb
542 def __repr__(self) -> str:
543 return (f"<AllocNode handle=0x{as_intptr(self._h_node):x}" 2ng
544 f" dptr=0x{self._dptr:x} size={self._bytesize}>") 2ng
546 @property
547 def dptr(self) -> int:
548 """The device pointer for the allocation."""
549 return self._dptr 28d9dOcPcQcRcScTc, - . / mbnbobpbUfVfUcsbTbUbVbWbjbkbVctbXbYbZb0bWcub1b2b3b4bXcvb%b(b*b,bYcwb[b^b`b|bZcxb}b~bacbc!dgbqb7 2cybcc3czbdc4cAbecy 5cBbfc6cCbgc7cDbhc8cEbic9cFbjc!cGbkc#cHblc$cIbmc
551 @property
552 def bytesize(self) -> int:
553 """The number of bytes allocated."""
554 return self._bytesize 2UfVfjbkb
556 @property
557 def device_id(self) -> int:
558 """The device on which the allocation was made."""
559 return self._device_id 2UfVfjbkb
561 @property
562 def memory_type(self) -> str:
563 """The type of memory: ``"device"``, ``"host"``, or ``"managed"``."""
564 return self._memory_type 2UfVfjbkbgb
566 @property
567 def peer_access(self) -> tuple[int, ...]:
568 """Device IDs with read-write access to this allocation."""
569 return self._peer_access 2UfVfjbkbhb
572cdef class FreeNode(GraphNode):
573 """A memory deallocation node.
575 Properties
576 ----------
577 dptr : int
578 The device pointer being freed.
579 """
581 @staticmethod
582 cdef FreeNode _create_with_params(GraphNodeHandle h_node,
583 cydriver.CUdeviceptr dptr):
584 """Create from known params (called by deallocate() builder)."""
585 cdef FreeNode n = FreeNode.__new__(FreeNode) 2OcPcQcRcScTc, - . / mbnbobpbUcVcWcXcYcZcqb2c3c4cy 5c6c7c8c9c!c#c$c
586 n._h_node = h_node 2OcPcQcRcScTc, - . / mbnbobpbUcVcWcXcYcZcqb2c3c4cy 5c6c7c8c9c!c#c$c
587 n._dptr = dptr 2OcPcQcRcScTc, - . / mbnbobpbUcVcWcXcYcZcqb2c3c4cy 5c6c7c8c9c!c#c$c
588 return n 2OcPcQcRcScTc, - . / mbnbobpbUcVcWcXcYcZcqb2c3c4cy 5c6c7c8c9c!c#c$c
590 @staticmethod
591 cdef FreeNode _create_from_driver(GraphNodeHandle h_node):
592 """Create by fetching params from the driver (called by _create factory)."""
593 cdef cydriver.CUgraphNode node = as_cu(h_node) 2qb
594 cdef cydriver.CUdeviceptr dptr
595 with nogil: 2qb
596 HANDLE_RETURN(cydriver.cuGraphMemFreeNodeGetParams(node, &dptr)) 2qb
597 return FreeNode._create_with_params(h_node, dptr) 2qb
599 def __repr__(self) -> str:
600 return f"<FreeNode handle=0x{as_intptr(self._h_node):x} dptr=0x{self._dptr:x}>" 2yg
602 @property
603 def dptr(self) -> int:
604 """The device pointer being freed."""
605 return self._dptr 2zgPbqb
608cdef class MemsetNode(GraphNode):
609 """A memset node.
611 Properties
612 ----------
613 dptr : int
614 The destination device pointer.
615 value : int
616 The fill value.
617 element_size : int
618 Element size in bytes (1, 2, or 4).
619 width : int
620 Width of the row in elements.
621 height : int
622 Number of rows.
623 pitch : int
624 Pitch in bytes (unused if height is 1).
625 """
627 @staticmethod
628 cdef MemsetNode _create_with_params(GraphNodeHandle h_node,
629 cydriver.CUdeviceptr dptr, unsigned int value,
630 unsigned int element_size, size_t width,
631 size_t height, size_t pitch):
632 """Create from known params (called by memset() builder)."""
633 cdef MemsetNode n = MemsetNode.__new__(MemsetNode) 2, - . / mbnbobpbTbUbVbWbXbYbZb0b1b2b3b4b%b(b*b,b[b^b`b|b}b~bacbc#d$d%d[ ?cm n ' ( 1d2dX E F P Q g nclbc ccdcecy fcgchcicjckclcmc
634 n._h_node = h_node 2, - . / mbnbobpbTbUbVbWbXbYbZb0b1b2b3b4b%b(b*b,b[b^b`b|b}b~bacbc#d$d%d[ ?cm n ' ( 1d2dX E F P Q g nclbc ccdcecy fcgchcicjckclcmc
635 n._dptr = dptr 2, - . / mbnbobpbTbUbVbWbXbYbZb0b1b2b3b4b%b(b*b,b[b^b`b|b}b~bacbc#d$d%d[ ?cm n ' ( 1d2dX E F P Q g nclbc ccdcecy fcgchcicjckclcmc
636 n._value = value 2, - . / mbnbobpbTbUbVbWbXbYbZb0b1b2b3b4b%b(b*b,b[b^b`b|b}b~bacbc#d$d%d[ ?cm n ' ( 1d2dX E F P Q g nclbc ccdcecy fcgchcicjckclcmc
637 n._element_size = element_size 2, - . / mbnbobpbTbUbVbWbXbYbZb0b1b2b3b4b%b(b*b,b[b^b`b|b}b~bacbc#d$d%d[ ?cm n ' ( 1d2dX E F P Q g nclbc ccdcecy fcgchcicjckclcmc
638 n._width = width 2, - . / mbnbobpbTbUbVbWbXbYbZb0b1b2b3b4b%b(b*b,b[b^b`b|b}b~bacbc#d$d%d[ ?cm n ' ( 1d2dX E F P Q g nclbc ccdcecy fcgchcicjckclcmc
639 n._height = height 2, - . / mbnbobpbTbUbVbWbXbYbZb0b1b2b3b4b%b(b*b,b[b^b`b|b}b~bacbc#d$d%d[ ?cm n ' ( 1d2dX E F P Q g nclbc ccdcecy fcgchcicjckclcmc
640 n._pitch = pitch 2, - . / mbnbobpbTbUbVbWbXbYbZb0b1b2b3b4b%b(b*b,b[b^b`b|b}b~bacbc#d$d%d[ ?cm n ' ( 1d2dX E F P Q g nclbc ccdcecy fcgchcicjckclcmc
641 return n 2, - . / mbnbobpbTbUbVbWbXbYbZb0b1b2b3b4b%b(b*b,b[b^b`b|b}b~bacbc#d$d%d[ ?cm n ' ( 1d2dX E F P Q g nclbc ccdcecy fcgchcicjckclcmc
643 @staticmethod
644 cdef MemsetNode _create_from_driver(GraphNodeHandle h_node):
645 """Create by fetching params from the driver (called by _create factory)."""
646 cdef cydriver.CUgraphNode node = as_cu(h_node) 1[
647 cdef cydriver.CUDA_MEMSET_NODE_PARAMS params
648 with nogil: 1[
649 HANDLE_RETURN(cydriver.cuGraphMemsetNodeGetParams(node, ¶ms)) 1[
650 return MemsetNode._create_with_params( 1[
651 h_node, params.dst, params.value,
652 params.elementSize, params.width, params.height, params.pitch) 1[
654 def __repr__(self) -> str:
655 return (f"<MemsetNode handle=0x{as_intptr(self._h_node):x}" 2og
656 f" dptr=0x{self._dptr:x} value={self._value}>") 2og
658 def update(
659 self,
660 *,
661 dst: Buffer | int | None = None,
662 value=None,
663 width: int | None = None,
664 height: int | None = None,
665 pitch: int | None = None,
666 dst_owner=None,
667 ) -> None:
668 """Replace selected memset parameters.
670 Omitted parameters preserve their current values. ``dst_owner`` may
671 only accompany a raw-address ``dst``.
673 With drivers from CUDA 12.2 through 13.1, the node's intended CUDA
674 context must be current when this method runs. With the CUDA 13 build
675 of ``cuda.core`` and a driver of CUDA 13.2 or newer, this method
676 preserves the recorded context.
678 .. warning::
680 Use caution when a retained operand owner directly or indirectly
681 owns a graph. Any reference cycle involving the owner and a graph
682 that retains it cannot be broken by Python's cyclic garbage
683 collector. Use a weak reference to break such cycles.
684 """
685 cdef OpaqueHandle dst_attachment_owner
686 GN_check_valid(self) 2m n ' ( 1d2dP Q g c
687 cdef GraphHandle h_graph
688 cdef cydriver.CUgraphNode node = as_cu(self._h_node) 1mn'(PQgc
689 cdef cydriver.CUcontext ctx = NULL 1mn'(PQgc
690 cdef cydriver.CUDA_MEMSET_NODE_PARAMS current
691 cdef cydriver.CUgraphNodeParams params
692 cdef cydriver.CUgraphNodeParams queried # no-cython-lint
694 if dst is None and dst_owner is not None: 1mn'(PQgc
695 raise ValueError("dst_owner requires dst") 1g
696 if (dst is None and value is None and width is None and 1mn'(PQgc
697 height is None and pitch is None): 1g
698 return 1g
700 c_memset(¶ms, 0, sizeof(params)) 1mn'(PQgc
701 params.type = cydriver.CU_GRAPH_NODE_TYPE_MEMSET 1mn'(PQgc
702 with nogil: 1mn'(PQgc
703 HANDLE_RETURN(cydriver.cuGraphMemsetNodeGetParams( 1mn'(PQgc
704 node, ¤t))
705 IF CUDA_CORE_BUILD_MAJOR >= 13:
706 if _check_node_get_params(): 1mn'(PQgc
707 _node_get_params(node, &queried) 1mn'(PQgc
708 ctx = queried.memset.ctx 1mn'(PQgc
709 else:
710 with nogil:
711 HANDLE_RETURN(cydriver.cuCtxGetCurrent(&ctx))
712 ELSE:
713 with nogil:
714 HANDLE_RETURN(cydriver.cuCtxGetCurrent(&ctx))
716 cdef cydriver.CUdeviceptr c_dst = current.dst 1mn'(PQgc
717 cdef unsigned int c_value = current.value 1mn'(PQgc
718 cdef unsigned int c_element_size = current.elementSize 1mn'(PQgc
719 cdef size_t c_width = current.width 1mn'(PQgc
720 cdef size_t c_height = current.height 1mn'(PQgc
721 cdef size_t c_pitch = current.pitch 1mn'(PQgc
723 if dst is None: 1mn'(PQgc
724 h_graph = graph_node_get_graph(self._h_node) 1nPQgc
725 HANDLE_RETURN(graph_get_attachment( 1nPQgc
726 h_graph, node,
727 &dst_attachment_owner, NULL))
728 else:
729 dst_attachment_owner = _resolve_memcpy_operand( 1m'(
730 dst, dst_owner, "dst", &c_dst) 1m'(
732 if value is not None: 1mnPQgc
733 c_value, c_element_size = _parse_fill_value(value) 1mnPQc
734 if width is not None: 1mngc
735 c_width = width 1g
736 if height is not None: 1mngc
737 c_height = height 1g
738 if pitch is not None: 1mngc
739 c_pitch = pitch 1g
741 params.memset.dst = c_dst 1mngc
742 params.memset.value = c_value 1mngc
743 params.memset.elementSize = c_element_size 1mngc
744 params.memset.width = c_width 1mngc
745 params.memset.height = c_height 1mngc
746 params.memset.pitch = c_pitch 1mngc
747 params.memset.ctx = ctx 1mngc
749 _set_definition_node_params( 1mngc
750 self._h_node, ¶ms, dst_attachment_owner,
751 OpaqueHandle(), params.memset.ctx)
752 self._dptr = c_dst 1mngc
753 self._value = c_value 1mngc
754 self._element_size = c_element_size 1mngc
755 self._width = c_width 1mngc
756 self._height = c_height 1mngc
757 self._pitch = c_pitch 1mngc
759 @property
760 def dptr(self) -> int:
761 """The destination device pointer."""
762 return self._dptr 2{e|e}e~ecbdbebfb?cm n E F P Q
764 @property
765 def value(self) -> int:
766 """The fill value."""
767 return self._value 2{e|e}e~ecbdbebfb?cm n E F P Q g
769 @property
770 def element_size(self) -> int:
771 """Element size in bytes (1, 2, or 4)."""
772 return self._element_size 2{e|e}e~ecbdbebfbm n E F P Q
774 @property
775 def width(self) -> int:
776 """Width of the row in elements."""
777 return self._width 2{e|e}e~ecbdbebfb?cm n E F P Q g
779 @property
780 def height(self) -> int:
781 """Number of rows."""
782 return self._height 2{e|e}e~ecbdbebfbm n E F P Q g
784 @property
785 def pitch(self) -> int:
786 """Pitch in bytes (unused if height is 1)."""
787 return self._pitch 2{e|e}e~ecbdbebfbm n E F P Q g
790cdef class MemcpyNode(GraphNode):
791 """A memcpy node.
793 Properties
794 ----------
795 dst : int
796 The destination pointer.
797 src : int
798 The source pointer.
799 size : int
800 The number of bytes copied.
801 """
803 @staticmethod
804 cdef MemcpyNode _create_with_params(GraphNodeHandle h_node,
805 cydriver.CUdeviceptr dst, cydriver.CUdeviceptr src,
806 size_t size, cydriver.CUmemorytype dst_type,
807 cydriver.CUmemorytype src_type):
808 """Create from known params (called by memcpy() builder)."""
809 cdef MemcpyNode n = MemcpyNode.__new__(MemcpyNode) 2, - . / sbtbubvbwbxbLeMe7 ibGcHcNeOePeQeReSeTeh l i v w x QdRdSdu W G H I r s t j k a b d e f 2 g nclbc ybzbAby BbCbDbEbFbGbHbIb
810 n._h_node = h_node 2, - . / sbtbubvbwbxbLeMe7 ibGcHcNeOePeQeReSeTeh l i v w x QdRdSdu W G H I r s t j k a b d e f 2 g nclbc ybzbAby BbCbDbEbFbGbHbIb
811 n._dst = dst 2, - . / sbtbubvbwbxbLeMe7 ibGcHcNeOePeQeReSeTeh l i v w x QdRdSdu W G H I r s t j k a b d e f 2 g nclbc ybzbAby BbCbDbEbFbGbHbIb
812 n._src = src 2, - . / sbtbubvbwbxbLeMe7 ibGcHcNeOePeQeReSeTeh l i v w x QdRdSdu W G H I r s t j k a b d e f 2 g nclbc ybzbAby BbCbDbEbFbGbHbIb
813 n._size = size 2, - . / sbtbubvbwbxbLeMe7 ibGcHcNeOePeQeReSeTeh l i v w x QdRdSdu W G H I r s t j k a b d e f 2 g nclbc ybzbAby BbCbDbEbFbGbHbIb
814 n._dst_type = dst_type 2, - . / sbtbubvbwbxbLeMe7 ibGcHcNeOePeQeReSeTeh l i v w x QdRdSdu W G H I r s t j k a b d e f 2 g nclbc ybzbAby BbCbDbEbFbGbHbIb
815 n._src_type = src_type 2, - . / sbtbubvbwbxbLeMe7 ibGcHcNeOePeQeReSeTeh l i v w x QdRdSdu W G H I r s t j k a b d e f 2 g nclbc ybzbAby BbCbDbEbFbGbHbIb
816 return n 2, - . / sbtbubvbwbxbLeMe7 ibGcHcNeOePeQeReSeTeh l i v w x QdRdSdu W G H I r s t j k a b d e f 2 g nclbc ybzbAby BbCbDbEbFbGbHbIb
818 @staticmethod
819 cdef MemcpyNode _create_from_driver(GraphNodeHandle h_node):
820 """Create by fetching params from the driver (called by _create factory)."""
821 cdef cydriver.CUgraphNode node = as_cu(h_node) 27 ibu a b d e f
822 cdef cydriver.CUDA_MEMCPY3D params
823 with nogil: 27 ibu a b d e f
824 HANDLE_RETURN(cydriver.cuGraphMemcpyNodeGetParams(node, ¶ms)) 27 ibu a b d e f
826 cdef cydriver.CUdeviceptr dst
827 cdef cydriver.CUdeviceptr src
828 if params.dstMemoryType == cydriver.CU_MEMORYTYPE_HOST: 27 ibu a b d e f
829 dst = <cydriver.CUdeviceptr><uintptr_t>params.dstHost 2ib
830 else:
831 dst = params.dstDevice 17uabdef
832 if params.srcMemoryType == cydriver.CU_MEMORYTYPE_HOST: 27 ibu a b d e f
833 src = <cydriver.CUdeviceptr><uintptr_t>params.srcHost 2ib
834 else:
835 src = params.srcDevice 17uabdef
837 return MemcpyNode._create_with_params( 27 ibu a b d e f
838 h_node, dst, src, params.WidthInBytes,
839 params.dstMemoryType, params.srcMemoryType) 27 ibu a b d e f
841 def __repr__(self) -> str:
842 cdef str dt = _memcpy_memory_type_tag(self._dst_type) 2f 0e
843 cdef str st = _memcpy_memory_type_tag(self._src_type) 2f 0e
844 return (f"<MemcpyNode handle=0x{as_intptr(self._h_node):x}" 2f 0e
845 f" dst=0x{self._dst:x}({dt}) src=0x{self._src:x}({st}) size={self._size}>") 2f 0e
847 def update(
848 self,
849 *,
850 dst: Buffer | int | None = None,
851 src: Buffer | int | None = None,
852 size: int | None = None,
853 dst_owner=None,
854 src_owner=None,
855 ) -> None:
856 """Replace selected memcpy parameters.
858 Omitted parameters preserve their current values. ``dst_owner`` and
859 ``src_owner`` may only accompany their corresponding raw addresses.
860 Multidimensional, pitched, offset, and array-backed memcpy nodes are
861 not supported. Nodes recorded by stream capture are supported.
863 With drivers from CUDA 12.2 through 13.1, the node's intended CUDA
864 context must be current when this method runs. With the CUDA 13 build
865 of ``cuda.core`` and a driver of CUDA 13.2 or newer, this method
866 preserves the recorded context.
868 .. warning::
870 Use caution when a retained operand owner directly or indirectly
871 owns a graph. Any reference cycle involving the owner and a graph
872 that retains it cannot be broken by Python's cyclic garbage
873 collector. Use a weak reference to break such cycles.
874 """
875 cdef cydriver.CUdeviceptr c_dst = self._dst 2h l i v w x QdRdSdr s t j k a b d e f 2 g c
876 cdef cydriver.CUdeviceptr c_src = self._src 2h l i v w x QdRdSdr s t j k a b d e f 2 g c
877 cdef OpaqueHandle dst_attachment_owner
878 cdef OpaqueHandle src_attachment_owner
879 GN_check_valid(self) 2h l i v w x QdRdSdr s t j k a b d e f 2 g c
880 cdef GraphHandle h_graph = graph_node_get_graph(self._h_node) 1hlivwxrstjkabdef2gc
881 cdef cydriver.CUgraphNode node = as_cu(self._h_node) 1hlivwxrstjkabdef2gc
882 cdef cydriver.CUcontext ctx = NULL 1hlivwxrstjkabdef2gc
883 cdef cydriver.CUgraphNodeParams params
884 cdef cydriver.CUmemorytype c_dst_type
885 cdef cydriver.CUmemorytype c_src_type
886 cdef cydriver.CUgraphNodeParams queried # no-cython-lint
888 if dst is None and dst_owner is not None: 1hlivwxrstjkabdef2gc
889 raise ValueError("dst_owner requires dst") 1g
890 if src is None and src_owner is not None: 1hlivwxrstjkabdef2gc
891 raise ValueError("src_owner requires src") 1g
892 if dst is None and src is None and size is None: 1hlivwxrstjkabdef2gc
893 return 1g
895 c_memset(¶ms, 0, sizeof(params)) 1hlivwxrstjkabdef2c
896 params.type = cydriver.CU_GRAPH_NODE_TYPE_MEMCPY 1hlivwxrstjkabdef2c
897 with nogil: 1hlivwxrstjkabdef2c
898 HANDLE_RETURN(cydriver.cuGraphMemcpyNodeGetParams( 1hlivwxrstjkabdef2c
899 node, ¶ms.memcpy.copyParams))
900 IF CUDA_CORE_BUILD_MAJOR >= 13:
901 if _check_node_get_params(): 1hlivwxrstjkabdef2c
902 _node_get_params(node, &queried) 1hlivwxrstjkabdef2c
903 ctx = queried.memcpy.copyCtx 1hlivwxrstjkabdef2c
904 else:
905 with nogil:
906 HANDLE_RETURN(cydriver.cuCtxGetCurrent(&ctx))
907 ELSE:
908 with nogil:
909 HANDLE_RETURN(cydriver.cuCtxGetCurrent(&ctx))
910 params.memcpy.copyCtx = ctx 1hlivwxrstjkabdef2c
912 if not _is_supported_memcpy_descriptor(¶ms.memcpy.copyParams): 1hlivwxrstjkabdef2c
913 raise NotImplementedError( 12
914 "updating multidimensional, pitched, offset, or array-backed "
915 "memcpy nodes is not supported")
917 # The descriptor check above admits HOST, DEVICE, and UNIFIED operands;
918 # the last two keep their address in the device-pointer field.
919 c_dst_type = params.memcpy.copyParams.dstMemoryType 1hlivwxrstjkabdefc
920 c_src_type = params.memcpy.copyParams.srcMemoryType 1hlivwxrstjkabdefc
921 if c_dst_type == cydriver.CU_MEMORYTYPE_HOST: 1hlivwxrstjkabdefc
922 c_dst = <cydriver.CUdeviceptr><uintptr_t>( 1hlivwxrstjkc
923 params.memcpy.copyParams.dstHost)
924 else:
925 c_dst = params.memcpy.copyParams.dstDevice 1abdef
926 if c_src_type == cydriver.CU_MEMORYTYPE_HOST: 1hlivwxrstjkabdefc
927 c_src = <cydriver.CUdeviceptr><uintptr_t>( 1hlivwxrstjkc
928 params.memcpy.copyParams.srcHost)
929 else:
930 c_src = params.memcpy.copyParams.srcDevice 1abdef
932 HANDLE_RETURN(graph_get_attachment( 1hlivwxrstjkabdefc
933 h_graph, node,
934 &dst_attachment_owner, &src_attachment_owner))
935 # A unified operand stays unified: any address is valid for that type,
936 # and an executable update rejects a change of memory type.
937 if dst is not None: 1hlivwxrstjkabdefc
938 dst_attachment_owner = _resolve_memcpy_operand( 1hkd
939 dst, dst_owner, "dst", &c_dst)
940 if c_dst_type != cydriver.CU_MEMORYTYPE_UNIFIED: 1hkd
941 c_dst_type = _get_memcpy_memory_type(c_dst) 1hk
942 params.memcpy.copyParams.dstMemoryType = c_dst_type 1hkd
943 params.memcpy.copyParams.dstHost = NULL 1hkd
944 params.memcpy.copyParams.dstDevice = 0 1hkd
945 params.memcpy.copyParams.dstArray = NULL 1hkd
946 params.memcpy.copyParams.reserved1 = NULL 1hkd
947 if c_dst_type == cydriver.CU_MEMORYTYPE_HOST: 1hkd
948 params.memcpy.copyParams.dstHost = <void*><uintptr_t>c_dst 1h
949 else:
950 params.memcpy.copyParams.dstDevice = c_dst 1kd
951 if src is not None: 1hlivwxrstjkabdefc
952 src_attachment_owner = _resolve_memcpy_operand( 1ivwxjabe
953 src, src_owner, "src", &c_src)
954 if c_src_type != cydriver.CU_MEMORYTYPE_UNIFIED: 1ijabe
955 c_src_type = _get_memcpy_memory_type(c_src) 1ij
956 params.memcpy.copyParams.srcMemoryType = c_src_type 1ijabe
957 params.memcpy.copyParams.srcHost = NULL 1ijabe
958 params.memcpy.copyParams.srcDevice = 0 1ijabe
959 params.memcpy.copyParams.srcArray = NULL 1ijabe
960 params.memcpy.copyParams.reserved0 = NULL 1ijabe
961 if c_src_type == cydriver.CU_MEMORYTYPE_HOST: 1ijabe
962 params.memcpy.copyParams.srcHost = <void*><uintptr_t>c_src 1i
963 else:
964 params.memcpy.copyParams.srcDevice = c_src 1jabe
965 if size is not None: 1hlirstjkabdefc
966 params.memcpy.copyParams.WidthInBytes = size 1lrstfc
968 _set_definition_node_params( 1hlijkabdefc
969 self._h_node, ¶ms,
970 dst_attachment_owner, src_attachment_owner,
971 params.memcpy.copyCtx)
972 self._dst = c_dst 1hlijkabdefc
973 self._src = c_src 1hlijkabdefc
974 self._size = params.memcpy.copyParams.WidthInBytes 1hlijkabdefc
975 self._dst_type = c_dst_type 1hlijkabdefc
976 self._src_type = c_src_type 1hlijkabdefc
978 @property
979 def dst(self) -> int:
980 """The destination pointer."""
981 return self._dst 2lgab7 ibh l i G H I r s t d e f g
983 @property
984 def src(self) -> int:
985 """The source pointer."""
986 return self._src 2lgab7 ibh l i G H I r s t a b d e f g
988 @property
989 def size(self) -> int:
990 """The number of bytes copied."""
991 return self._size 2lgab7 ibh l i G H I r s t d e f g
994cdef class ChildGraphNode(GraphNode):
995 """A child graph node.
997 Properties
998 ----------
999 child_graph : GraphDefinition
1000 The embedded graph definition (non-owning wrapper).
1001 """
1003 @staticmethod
1004 cdef ChildGraphNode _create_with_params(GraphNodeHandle h_node,
1005 GraphHandle h_child_graph):
1006 """Create from known params (called by embed() builder)."""
1007 cdef ChildGraphNode n = ChildGraphNode.__new__(ChildGraphNode) 2QbydzdAdBdCdDdEd_ MbL Wf` 3d{ ^ Rb| N 0dU 1 Td@cK : FdGdHdy IdJdKdLdMdNdOdPd
1008 n._h_node = h_node 2QbydzdAdBdCdDdEd_ MbL Wf` 3d{ ^ Rb| N 0dU 1 Td@cK : FdGdHdy IdJdKdLdMdNdOdPd
1009 n._h_child_graph = h_child_graph 2QbydzdAdBdCdDdEd_ MbL Wf` 3d{ ^ Rb| N 0dU 1 Td@cK : FdGdHdy IdJdKdLdMdNdOdPd
1010 return n 2QbydzdAdBdCdDdEd_ MbL Wf` 3d{ ^ Rb| N 0dU 1 Td@cK : FdGdHdy IdJdKdLdMdNdOdPd
1012 @staticmethod
1013 cdef ChildGraphNode _create_from_driver(GraphNodeHandle h_node):
1014 """Create by fetching params from the driver (called by _create factory)."""
1015 cdef cydriver.CUgraphNode node = as_cu(h_node) 1_L`{^|N
1016 cdef cydriver.CUgraph child_graph = NULL 1_L`{^|N
1017 with nogil: 1_L`{^|N
1018 HANDLE_RETURN(cydriver.cuGraphChildGraphNodeGetGraph(node, &child_graph)) 1_L`{^|N
1019 cdef GraphHandle h_graph = graph_node_get_graph(h_node) 1_L`{^|N
1020 cdef GraphHandle h_child = create_child_graph_handle( 1_L`{^|N
1021 child_graph, h_graph, node)
1022 return ChildGraphNode._create_with_params(h_node, h_child) 1_L`{^|N
1024 def __repr__(self) -> str:
1025 return (f"<ChildGraphNode handle=0x{as_intptr(self._h_node):x}" 20dpg
1026 f" child=0x{as_intptr(self._h_child_graph):x}>") 20dpg
1028 def update(self, GraphDefinition child not None: GraphDefinition) -> None:
1029 """Replace the embedded graph with a clone of ``child``.
1031 ``child`` must belong to an independent graph hierarchy.
1032 """
1033 GN_check_valid(self) 2L N 1 @c:
1034 GD_check_valid(child) 1LN1:
1035 cdef GraphHandle h_parent = graph_node_get_graph(self._h_node) 1LN1:
1036 cdef GraphHandle h_replacement
1037 cdef cydriver.CUgraphNode node = as_cu(self._h_node) 1LN1:
1038 cdef cydriver.CUgraphNodeParams params
1039 cdef cydriver.CUresult commit_status
1040 cdef PreparedChildGraphUpdate prepared
1042 _require_graph_node_update_support() 1LN1:
1043 c_memset(¶ms, 0, sizeof(params)) 1LN1:
1044 params.type = cydriver.CU_GRAPH_NODE_TYPE_GRAPH 1LN1:
1045 params.graph.graph = as_cu(child._h_graph) 1LN1:
1047 HANDLE_RETURN(graph_prepare_child_graph_update( 1LN1:
1048 h_parent, self._h_child_graph, node,
1049 child._h_graph, &prepared))
1050 with nogil: 1LN1
1051 HANDLE_RETURN(cydriver.cuGraphNodeSetParams( 1LN1
1052 node, ¶ms))
1053 try: 1LN1
1054 commit_status = graph_commit_child_graph_update( 1LN1
1055 prepared, &h_replacement)
1056 finally:
1057 if h_replacement: 1LN1
1058 self._h_child_graph = h_replacement 1LN1
1059 HANDLE_RETURN(commit_status) 1LN1
1061 @property
1062 def child_graph(self) -> GraphDefinition:
1063 """The embedded graph definition (non-owning wrapper)."""
1064 return GraphDefinition._from_handle(self._h_child_graph) 2QbrcAg_ MbL Wf` { ^ Rb| N 0d1 Td@cK :
1067cdef class EventRecordNode(GraphNode):
1068 """An event record node.
1070 Properties
1071 ----------
1072 event : Event
1073 The event being recorded.
1074 """
1076 @staticmethod
1077 cdef EventRecordNode _create_with_params(GraphNodeHandle h_node,
1078 EventHandle h_event):
1079 """Create from known params (called by record() builder)."""
1080 cdef EventRecordNode n = EventRecordNode.__new__(EventRecordNode) 2Ue'c)c+c-c/c;cXf0cYfVeWegbhbIcJcqb7 ib%c; ) 5fXeZfKc4 R @eUd6f7f8fy 9f!f#f$f%f'f(f)f
1081 n._h_node = h_node 2Ue'c)c+c-c/c;cXf0cYfVeWegbhbIcJcqb7 ib%c; ) 5fXeZfKc4 R @eUd6f7f8fy 9f!f#f$f%f'f(f)f
1082 n._h_event = h_event 2Ue'c)c+c-c/c;cXf0cYfVeWegbhbIcJcqb7 ib%c; ) 5fXeZfKc4 R @eUd6f7f8fy 9f!f#f$f%f'f(f)f
1083 return n 2Ue'c)c+c-c/c;cXf0cYfVeWegbhbIcJcqb7 ib%c; ) 5fXeZfKc4 R @eUd6f7f8fy 9f!f#f$f%f'f(f)f
1085 @staticmethod
1086 cdef EventRecordNode _create_from_driver(GraphNodeHandle h_node):
1087 """Create by fetching params from the driver (called by _create factory)."""
1088 cdef cydriver.CUgraphNode node = as_cu(h_node) 2IcKc
1089 cdef cydriver.CUevent event
1090 with nogil: 2IcKc
1091 HANDLE_RETURN(cydriver.cuGraphEventRecordNodeGetEvent(node, &event)) 2IcKc
1092 cdef EventHandle h_event = create_event_handle_ref(event) 2IcKc
1093 return EventRecordNode._create_with_params(h_node, h_event) 2IcKc
1095 def __repr__(self) -> str:
1096 return (f"<EventRecordNode handle=0x{as_intptr(self._h_node):x}" 2qg
1097 f" event=0x{as_intptr(self._h_event):x}>") 2qg
1099 def update(self, Event event not None: Event) -> None:
1100 """Replace the event recorded by this node."""
1101 GN_check_valid(self) 2; Zf@e
1102 Event_check_open(event) 2; @e
1103 cdef OpaqueHandle event_owner = event._h_event 1;
1104 cdef cydriver.CUgraphNodeParams params
1106 c_memset(¶ms, 0, sizeof(params)) 1;
1107 params.type = cydriver.CU_GRAPH_NODE_TYPE_EVENT_RECORD 1;
1108 params.eventRecord.event = as_cu(event._h_event) 1;
1110 _set_definition_node_params( 1;
1111 self._h_node, ¶ms, event_owner)
1112 self._h_event = event._h_event 1;
1114 @property
1115 def event(self) -> Event:
1116 """The event being recorded."""
1117 return Event._from_handle(self._h_event) 2BgNbXf0cYfIc; 4 @e
1120cdef class EventWaitNode(GraphNode):
1121 """An event wait node.
1123 Properties
1124 ----------
1125 event : Event
1126 The event being waited on.
1127 """
1129 @staticmethod
1130 cdef EventWaitNode _create_with_params(GraphNodeHandle h_node,
1131 EventHandle h_event):
1132 """Create from known params (called by wait() builder)."""
1133 cdef EventWaitNode n = EventWaitNode.__new__(EventWaitNode) 2Ue(c*c,c.c:c=cVeWe1c0fIcJc) XeKcR Ud*f+f,fy -f.f/f:f;f=f?f@f
1134 n._h_node = h_node 2Ue(c*c,c.c:c=cVeWe1c0fIcJc) XeKcR Ud*f+f,fy -f.f/f:f;f=f?f@f
1135 n._h_event = h_event 2Ue(c*c,c.c:c=cVeWe1c0fIcJc) XeKcR Ud*f+f,fy -f.f/f:f;f=f?f@f
1136 return n 2Ue(c*c,c.c:c=cVeWe1c0fIcJc) XeKcR Ud*f+f,fy -f.f/f:f;f=f?f@f
1138 @staticmethod
1139 cdef EventWaitNode _create_from_driver(GraphNodeHandle h_node):
1140 """Create by fetching params from the driver (called by _create factory)."""
1141 cdef cydriver.CUgraphNode node = as_cu(h_node) 2Jc
1142 cdef cydriver.CUevent event
1143 with nogil: 2Jc
1144 HANDLE_RETURN(cydriver.cuGraphEventWaitNodeGetEvent(node, &event)) 2Jc
1145 cdef EventHandle h_event = create_event_handle_ref(event) 2Jc
1146 return EventWaitNode._create_with_params(h_node, h_event) 2Jc
1148 def __repr__(self) -> str:
1149 return (f"<EventWaitNode handle=0x{as_intptr(self._h_node):x}" 2rg
1150 f" event=0x{as_intptr(self._h_event):x}>") 2rg
1152 def update(self, Event event not None: Event) -> None:
1153 """Replace the event waited on by this node."""
1154 GN_check_valid(self) 2) KcUd
1155 Event_check_open(event) 2) Ud
1156 cdef OpaqueHandle event_owner = event._h_event 1)
1157 cdef cydriver.CUgraphNodeParams params
1159 c_memset(¶ms, 0, sizeof(params)) 1)
1160 params.type = cydriver.CU_GRAPH_NODE_TYPE_WAIT_EVENT 1)
1161 params.eventWait.event = as_cu(event._h_event) 1)
1163 _set_definition_node_params( 1)
1164 self._h_node, ¶ms, event_owner)
1165 self._h_event = event._h_event 1)
1167 @property
1168 def event(self) -> Event:
1169 """The event being waited on."""
1170 return Event._from_handle(self._h_event) 2CgOb1c0fJc) R Ud
1173cdef class HostCallbackNode(GraphNode):
1174 """A host callback node.
1176 Properties
1177 ----------
1178 callback : callable or None
1179 The Python callable (None for ctypes function pointer callbacks).
1180 """
1182 @staticmethod
1183 cdef HostCallbackNode _create_with_params(GraphNodeHandle h_node,
1184 object callable_obj, cydriver.CUhostFn fn,
1185 void* user_data):
1186 """Create from known params (called by callback() builder)."""
1187 cdef HostCallbackNode n = HostCallbackNode.__new__(HostCallbackNode) 2afbfcfdfefYeQbffgfhfifjfkflfmfnfofpfqfrfsftf5duf_ vfwfxfyfL ` 3d8 5 9 ! # 6 $ % GcHc{ zfRbAf| N BfFcU z 4d1 * + TdCfZe@c[e]eV K S T Y : 'd(dO A Z 0 6d7dDfEflbFfGfHfy IfJfKfLfMfNfOfPf
1188 n._h_node = h_node 2afbfcfdfefYeQbffgfhfifjfkflfmfnfofpfqfrfsftf5duf_ vfwfxfyfL ` 3d8 5 9 ! # 6 $ % GcHc{ zfRbAf| N BfFcU z 4d1 * + TdCfZe@c[e]eV K S T Y : 'd(dO A Z 0 6d7dDfEflbFfGfHfy IfJfKfLfMfNfOfPf
1189 n._callable = callable_obj 2afbfcfdfefYeQbffgfhfifjfkflfmfnfofpfqfrfsftf5duf_ vfwfxfyfL ` 3d8 5 9 ! # 6 $ % GcHc{ zfRbAf| N BfFcU z 4d1 * + TdCfZe@c[e]eV K S T Y : 'd(dO A Z 0 6d7dDfEflbFfGfHfy IfJfKfLfMfNfOfPf
1190 n._fn = fn 2afbfcfdfefYeQbffgfhfifjfkflfmfnfofpfqfrfsftf5duf_ vfwfxfyfL ` 3d8 5 9 ! # 6 $ % GcHc{ zfRbAf| N BfFcU z 4d1 * + TdCfZe@c[e]eV K S T Y : 'd(dO A Z 0 6d7dDfEflbFfGfHfy IfJfKfLfMfNfOfPf
1191 n._user_data = user_data 2afbfcfdfefYeQbffgfhfifjfkflfmfnfofpfqfrfsftf5duf_ vfwfxfyfL ` 3d8 5 9 ! # 6 $ % GcHc{ zfRbAf| N BfFcU z 4d1 * + TdCfZe@c[e]eV K S T Y : 'd(dO A Z 0 6d7dDfEflbFfGfHfy IfJfKfLfMfNfOfPf
1192 return n 2afbfcfdfefYeQbffgfhfifjfkflfmfnfofpfqfrfsftf5duf_ vfwfxfyfL ` 3d8 5 9 ! # 6 $ % GcHc{ zfRbAf| N BfFcU z 4d1 * + TdCfZe@c[e]eV K S T Y : 'd(dO A Z 0 6d7dDfEflbFfGfHfy IfJfKfLfMfNfOfPf
1194 @staticmethod
1195 cdef HostCallbackNode _create_from_driver(GraphNodeHandle h_node):
1196 """Create by fetching params from the driver (called by _create factory)."""
1197 cdef cydriver.CUgraphNode node = as_cu(h_node) 2Qb_ L ` { Rb| N 1 K :
1198 cdef cydriver.CUDA_HOST_NODE_PARAMS params
1199 with nogil: 2Qb_ L ` { Rb| N 1 K :
1200 HANDLE_RETURN(cydriver.cuGraphHostNodeGetParams(node, ¶ms)) 2Qb_ L ` { Rb| N 1 K :
1202 cdef object callable_obj = None 2Qb_ L ` { Rb| N 1 K :
1203 if _is_py_host_trampoline(params.fn): 2Qb_ L ` { Rb| N 1 K :
1204 callable_obj = <object>params.userData 2Qb_ L ` { Rb| N 1 K :
1206 return HostCallbackNode._create_with_params( 2Qb_ L ` { Rb| N 1 K :
1207 h_node, callable_obj, params.fn, params.userData) 2Qb_ L ` { Rb| N 1 K :
1209 def __repr__(self) -> str:
1210 if self._callable is not None: 24d[f
1211 name = getattr(self._callable, '__name__', '?') 2[f
1212 return (f"<HostCallbackNode handle=0x{as_intptr(self._h_node):x}" 2[f
1213 f" callback={name}>") 2[f
1214 return (f"<HostCallbackNode handle=0x{as_intptr(self._h_node):x}" 24d
1215 f" cfunc=0x{<uintptr_t>self._fn:x}>") 24d
1217 def update(self, fn, *, user_data=None) -> None:
1218 """Replace the callback and user-data binding for this node.
1220 ``fn`` accepts the same forms as :meth:`~graph.GraphNode.callback`: a
1221 Python callable, or a ctypes function pointer whose declared prototype
1222 matches ``CUhostFn`` (``void (*)(void*)``). A mismatched ctypes
1223 prototype raises ``TypeError``. ``user_data`` with a Python callable,
1224 or :data:`HOST_COPY_FN` without a packed record, raises
1225 ``ValueError``.
1227 .. warning::
1229 Callbacks must not call CUDA API functions. Doing so may
1230 deadlock or corrupt driver state.
1232 Use caution when a Python callback retains an object that owns a
1233 graph. Any reference cycle involving the callback and a graph that
1234 retains it cannot be broken by Python's cyclic garbage collector.
1235 Use a weak reference to break such cycles.
1236 """
1237 GN_check_valid(self) 2Ye* + Ze[e]e'd(d
1238 cdef cydriver.CUhostFn c_fn
1239 cdef void* c_user_data
1240 cdef OpaqueHandle fn_owner, data_owner
1241 cdef cydriver.CUgraphNodeParams params
1243 _resolve_host_callback( 2Ye* + Ze'd(d
1244 fn, user_data, &c_fn, &c_user_data, &fn_owner, &data_owner)
1245 c_memset(¶ms, 0, sizeof(params)) 1*+
1246 params.type = cydriver.CU_GRAPH_NODE_TYPE_HOST 1*+
1247 params.host.fn = c_fn 1*+
1248 params.host.userData = c_user_data 1*+
1250 _set_definition_node_params( 1*+
1251 self._h_node, ¶ms, fn_owner, data_owner)
1252 self._callable = fn if _is_py_host_trampoline(c_fn) else None 1*+
1253 self._fn = c_fn 1*+
1254 self._user_data = c_user_data 1*+
1256 @property
1257 def callback(self):
1258 """The Python callable, or None for ctypes function pointer callbacks."""
1259 return self._callable 2DgEgL 4d1 * + K S T : 'd(d
1262cdef class ConditionalNode(GraphNode):
1263 """Base class for conditional nodes.
1265 When created via builder methods (if_then, if_else, while_loop, switch),
1266 a specific subclass (IfNode, IfElseNode, WhileNode, SwitchNode) is
1267 returned. When reconstructed from the driver on CUDA 13.2+, the
1268 correct subclass is determined via cuGraphNodeGetParams. On older
1269 drivers, this base class is used as a fallback.
1271 Properties
1272 ----------
1273 condition : GraphCondition or None
1274 The condition variable controlling execution (None pre-13.2).
1275 cond_type : str or None
1276 The conditional type ("if", "while", or "switch"; None pre-13.2).
1277 branches : tuple of GraphDefinition
1278 The body graphs for each branch (empty pre-13.2).
1279 """
1281 @staticmethod
1282 cdef ConditionalNode _create_from_driver(GraphNodeHandle h_node):
1283 cdef ConditionalNode n
1284 if not _check_node_get_params(): 1859!#6$%@
1285 n = ConditionalNode.__new__(ConditionalNode)
1286 n._h_node = h_node
1287 n._condition = None
1288 n._cond_type = cydriver.CU_GRAPH_COND_TYPE_IF
1289 n._branches = ()
1290 return n
1291 IF CUDA_CORE_BUILD_MAJOR >= 13:
1292 return ConditionalNode._create_from_driver_params(h_node) 1859!#6$%@
1293 ELSE:
1294 raise AssertionError("unreachable: cuGraphNodeGetParams needs the CUDA 13 build")
1296 IF CUDA_CORE_BUILD_MAJOR >= 13:
1297 @staticmethod
1298 cdef ConditionalNode _create_from_driver_params(GraphNodeHandle h_node):
1299 cdef ConditionalNode n
1300 cdef cydriver.CUgraphNode node = as_cu(h_node) 1859!#6$%@
1301 cdef cydriver.CUgraphNodeParams params
1302 _node_get_params(node, ¶ms) 1859!#6$%@
1303 cdef int cond_type_int = <int>params.conditional.type 1859!#6$%@
1304 cdef unsigned int size = params.conditional.size 1859!#6$%@
1306 cdef GraphCondition condition = GraphCondition.__new__(GraphCondition) 1859!#6$%@
1307 condition._c_handle = params.conditional.handle 1859!#6$%@
1309 cdef GraphHandle h_graph = graph_node_get_graph(h_node) 1859!#6$%@
1310 cdef list branch_list = [] 1859!#6$%@
1311 cdef unsigned int i
1312 cdef GraphHandle h_branch
1313 if params.conditional.phGraph_out != NULL: 1859!#6$%@
1314 for i in range(size): 1859!#6$%@
1315 h_branch = create_child_graph_handle( 1859!#6$%@
1316 params.conditional.phGraph_out[i], h_graph, node)
1317 branch_list.append(GraphDefinition._from_handle(h_branch)) 1859!#6$%@
1318 cdef tuple branches = tuple(branch_list) 1859!#6$%@
1320 cdef type cls
1321 if cond_type_int == <int>cydriver.CU_GRAPH_COND_TYPE_IF: 1859!#6$%@
1322 if size == 1: 185#6
1323 cls = IfNode 18#
1324 else:
1325 cls = IfElseNode 156
1326 elif cond_type_int == <int>cydriver.CU_GRAPH_COND_TYPE_WHILE: 19!$%@
1327 cls = WhileNode 1!%@
1328 else:
1329 cls = SwitchNode 19$
1331 n = cls.__new__(cls) 1859!#6$%@
1332 n._h_node = h_node 1859!#6$%@
1333 n._condition = condition 1859!#6$%@
1334 n._cond_type = <cydriver.CUgraphConditionalNodeType>cond_type_int 1859!#6$%@
1335 n._branches = branches 1859!#6$%@
1336 return n 1859!#6$%@
1338 def __repr__(self) -> str:
1339 return f"<ConditionalNode handle=0x{as_intptr(self._h_node):x}>"
1341 @property
1342 def condition(self) -> GraphCondition | None:
1343 """The condition variable controlling execution."""
1344 return self._condition 2^eQf1fRf_eSf2fTf
1346 @property
1347 def cond_type(self) -> GraphConditionalType | None:
1348 """The conditional type: GraphConditionalType.IF, .WHILE, or .SWITCH
1350 Returns None when reconstructed from the driver pre-CUDA 13.2,
1351 as the conditional type cannot be determined.
1352 """
1353 if self._condition is None: 2^eQf1fRf_eSf2fTf
1354 return None
1355 if self._cond_type == cydriver.CU_GRAPH_COND_TYPE_IF: 2^eQf1fRf_eSf2fTf
1356 return GraphConditionalType("if") 2^eQf_eSf
1357 elif self._cond_type == cydriver.CU_GRAPH_COND_TYPE_WHILE:
1358 return GraphConditionalType("while") 2RfTf
1359 else:
1360 return GraphConditionalType("switch") 21f2f
1362 @property
1363 def branches(self) -> tuple[GraphDefinition, ...]:
1364 """The body graphs for each branch as a tuple of GraphDefinition.
1366 Returns an empty tuple when reconstructed from the driver
1367 pre-CUDA 13.2.
1368 """
1369 return self._branches 2^eQf1fRf_eSf2fTfFgzc9 $ @
1372cdef class IfNode(ConditionalNode):
1373 """An if-conditional node."""
1375 def __repr__(self) -> str:
1376 return (f"<IfNode handle=0x{as_intptr(self._h_node):x}" 2sg
1377 f" condition=0x{<unsigned long long>self._condition._c_handle:x}>") 2sg
1379 @property
1380 def then(self) -> GraphDefinition:
1381 """The 'then' branch graph."""
1382 return self._branches[0] 2QfSfGgyc8 #
1385cdef class IfElseNode(ConditionalNode):
1386 """An if-else conditional node."""
1388 def __repr__(self) -> str:
1389 return (f"<IfElseNode handle=0x{as_intptr(self._h_node):x}" 2tg
1390 f" condition=0x{<unsigned long long>self._condition._c_handle:x}>") 2tg
1392 @property
1393 def then(self) -> GraphDefinition:
1394 """The ``then`` branch graph (executed when condition is non-zero)."""
1395 return self._branches[0] 2^e_eugoc5 6
1397 @property
1398 def else_(self) -> GraphDefinition:
1399 """The ``else`` branch graph (executed when condition is zero)."""
1400 return self._branches[1] 2^e_eugoc5 6
1403cdef class WhileNode(ConditionalNode):
1404 """A while-loop conditional node."""
1406 def __repr__(self) -> str:
1407 return (f"<WhileNode handle=0x{as_intptr(self._h_node):x}" 2vg
1408 f" condition=0x{<unsigned long long>self._condition._c_handle:x}>") 2vg
1410 @property
1411 def body(self) -> GraphDefinition:
1412 """The loop body graph."""
1413 return self._branches[0] 2RfTfHgAc! %
1416cdef class SwitchNode(ConditionalNode):
1417 """A switch conditional node."""
1419 def __repr__(self) -> str:
1420 return (f"<SwitchNode handle=0x{as_intptr(self._h_node):x}" 2wg
1421 f" condition=0x{<unsigned long long>self._condition._c_handle:x}>") 2wg
1424cdef class ExecutableGraphNode:
1425 """A lightweight view pairing an executable graph with a source node.
1427 Create executable-node views with ``graph[node]``. CUDA validates that the
1428 node identifies a node in the executable graph when an operation is
1429 performed.
1430 """
1432 def __init__(self):
1433 raise RuntimeError( 2Ig
1434 "directly constructing an executable graph node is not supported")
1436 def __repr__(self) -> str:
1437 return ( 2Sb
1438 f"<{type(self).__name__} graph=0x{as_intptr(self._h_graph_exec):x}" 2Sb
1439 f" node=0x{as_intptr(self._h_node):x}>" 2Sb
1440 )
1443cdef class ExecutableKernelNode(ExecutableGraphNode):
1444 """An executable kernel-node view."""
1446 def update(
1447 self,
1448 *,
1449 LaunchConfig config not None: LaunchConfig,
1450 Kernel kernel not None: Kernel,
1451 args,
1452 ) -> None:
1453 """Replace all kernel launch parameters for future launches.
1455 ``args`` must contain the complete argument sequence; use ``args=()``
1456 for a no-argument kernel. Clustered and cooperative launch
1457 configurations are not supported.
1458 """
1459 cdef LaunchConfig c_config = config 2z M JbKbB C D A J
1460 cdef Kernel c_kernel = kernel 2z M JbKbB C D A J
1461 cdef ParamHolder arg_holder
1462 cdef object kernel_args
1463 cdef OpaqueHandle kernel_owner = c_kernel._h_kernel 2z M JbKbB C D A J
1464 cdef OpaqueHandle args_owner
1465 cdef cydriver.CUgraphNodeParams params
1467 if c_config.cluster is not None or c_config.is_cooperative: 2z M JbKbB C D A J
1468 raise NotImplementedError( 2JbKb
1469 "updating clustered or cooperative kernel nodes is not "
1470 "supported")
1471 arg_holder = ParamHolder(args) 1zMBCDAJ
1473 c_memset(¶ms, 0, sizeof(params)) 1zMBCDAJ
1474 params.type = cydriver.CU_GRAPH_NODE_TYPE_KERNEL 1zMBCDAJ
1475 params.kernel.kern = as_cu(c_kernel._h_kernel) 1zMBCDAJ
1476 params.kernel.func = <cydriver.CUfunction>NULL 1zMBCDAJ
1477 params.kernel.gridDimX = c_config.grid[0] 1zMBCDAJ
1478 params.kernel.gridDimY = c_config.grid[1] 1zMBCDAJ
1479 params.kernel.gridDimZ = c_config.grid[2] 1zMBCDAJ
1480 params.kernel.blockDimX = c_config.block[0] 1zMBCDAJ
1481 params.kernel.blockDimY = c_config.block[1] 1zMBCDAJ
1482 params.kernel.blockDimZ = c_config.block[2] 1zMBCDAJ
1483 params.kernel.sharedMemBytes = c_config.shmem_size 1zMBCDAJ
1484 params.kernel.kernelParams = <void**><uintptr_t>arg_holder.ptr 1zMBCDAJ
1485 params.kernel.extra = NULL 1zMBCDAJ
1486 params.kernel.ctx = <cydriver.CUcontext>NULL 1zMBCDAJ
1488 kernel_args = arg_holder.kernel_args 1zMBCDAJ
1489 if kernel_args is not None: 1zMBCDAJ
1490 args_owner = make_opaque_py(kernel_args) 1zBCAJ
1491 _set_executable_node_params( 1zMBCDAJ
1492 self._h_graph_exec, self._h_node, ¶ms,
1493 kernel_owner, args_owner)
1495 @property
1496 def is_enabled(self) -> bool:
1497 """Whether this node is enabled in the executable graph."""
1498 return _get_executable_node_enabled( 1}3
1499 self._h_graph_exec, self._h_node) 1}3
1501 def enable(self) -> None:
1502 """Enable this node in the executable graph."""
1503 _set_executable_node_enabled( 1~3
1504 self._h_graph_exec, self._h_node, True)
1506 def disable(self) -> None:
1507 """Disable this node in the executable graph."""
1508 _set_executable_node_enabled( 13
1509 self._h_graph_exec, self._h_node, False)
1512cdef class ExecutableMemsetNode(ExecutableGraphNode):
1513 """An executable memset-node view."""
1515 def update(
1516 self,
1517 *,
1518 dst: Buffer | int,
1519 value,
1520 size_t width,
1521 size_t height=1,
1522 size_t pitch=0,
1523 ) -> None:
1524 """Replace all memset parameters for future launches."""
1525 cdef cydriver.CUdeviceptr c_dst
1526 cdef OpaqueHandle dst_owner = _resolve_memcpy_operand( 1EF
1527 dst, None, "dst", &c_dst)
1528 cdef unsigned int c_value
1529 cdef unsigned int element_size
1530 c_value, element_size = _parse_fill_value(value) 1EF
1532 cdef cydriver.CUcontext ctx = NULL 1EF
1533 cdef cydriver.CUgraphNodeParams params
1534 with nogil: 1EF
1535 HANDLE_RETURN(cydriver.cuCtxGetCurrent(&ctx)) 1EF
1537 c_memset(¶ms, 0, sizeof(params)) 1EF
1538 params.type = cydriver.CU_GRAPH_NODE_TYPE_MEMSET 1EF
1539 params.memset.dst = c_dst 1EF
1540 params.memset.value = c_value 1EF
1541 params.memset.elementSize = element_size 1EF
1542 params.memset.width = width 1EF
1543 params.memset.height = height 1EF
1544 params.memset.pitch = pitch 1EF
1545 params.memset.ctx = ctx 1EF
1546 _set_executable_node_params( 1EF
1547 self._h_graph_exec, self._h_node, ¶ms, dst_owner)
1549 @property
1550 def is_enabled(self) -> bool:
1551 """Whether this node is enabled in the executable graph."""
1552 return _get_executable_node_enabled( 1X
1553 self._h_graph_exec, self._h_node) 1X
1555 def enable(self) -> None:
1556 """Enable this node in the executable graph."""
1557 _set_executable_node_enabled( 1X
1558 self._h_graph_exec, self._h_node, True)
1560 def disable(self) -> None:
1561 """Disable this node in the executable graph."""
1562 _set_executable_node_enabled( 1X
1563 self._h_graph_exec, self._h_node, False)
1566cdef class ExecutableMemcpyNode(ExecutableGraphNode):
1567 """An executable memcpy-node view."""
1569 def update(
1570 self,
1571 *,
1572 dst: Buffer | int,
1573 src: Buffer | int,
1574 size_t size,
1575 ) -> None:
1576 """Replace all one-dimensional memcpy parameters for future launches.
1578 Nodes recorded by stream capture are supported.
1579 """
1580 cdef cydriver.CUdeviceptr c_dst
1581 cdef cydriver.CUdeviceptr c_src
1582 cdef OpaqueHandle dst_owner = _resolve_memcpy_operand( 1uGHIab
1583 dst, None, "dst", &c_dst)
1584 cdef OpaqueHandle src_owner = _resolve_memcpy_operand( 1uGHIab
1585 src, None, "src", &c_src)
1586 cdef cydriver.CUmemorytype dst_type
1587 cdef cydriver.CUmemorytype src_type
1588 cdef cydriver.CUcontext ctx = NULL 1uGHIab
1589 cdef cydriver.CUgraphNodeParams params
1590 cdef cydriver.CUDA_MEMCPY3D recorded
1591 cdef cydriver.CUgraphNode node = as_cu(self._h_node) 1uGHIab
1593 c_memset(¶ms, 0, sizeof(params)) 1uGHIab
1594 params.type = cydriver.CU_GRAPH_NODE_TYPE_MEMCPY 1uGHIab
1595 _init_memcpy_params( 1uGHIab
1596 c_dst, c_src, size, ¶ms.memcpy.copyParams,
1597 &dst_type, &src_type)
1598 # A destroyed node is reported by _set_executable_node_params below.
1599 # The memory types are read from the definition node, not from the
1600 # instantiated graph. That is correct only while MemcpyNode.update()
1601 # keeps a unified operand unified, which it does; an executable update
1602 # rejects a change of memory type.
1603 if node != NULL: 1uGHIab
1604 with nogil: 1uGHIab
1605 HANDLE_RETURN(cydriver.cuGraphMemcpyNodeGetParams( 1uGHIab
1606 node, &recorded))
1607 if recorded.dstMemoryType == cydriver.CU_MEMORYTYPE_UNIFIED: 1uGHIab
1608 params.memcpy.copyParams.dstMemoryType = ( 1uab
1609 cydriver.CU_MEMORYTYPE_UNIFIED)
1610 params.memcpy.copyParams.dstHost = NULL 1uab
1611 params.memcpy.copyParams.dstDevice = c_dst 1uab
1612 if recorded.srcMemoryType == cydriver.CU_MEMORYTYPE_UNIFIED: 1uGHIab
1613 params.memcpy.copyParams.srcMemoryType = ( 1uab
1614 cydriver.CU_MEMORYTYPE_UNIFIED)
1615 params.memcpy.copyParams.srcHost = NULL 1uab
1616 params.memcpy.copyParams.srcDevice = c_src 1uab
1617 with nogil: 1uGHIab
1618 HANDLE_RETURN(cydriver.cuCtxGetCurrent(&ctx)) 1uGHIab
1619 params.memcpy.copyCtx = ctx 1uGHIab
1620 _set_executable_node_params( 1uGHIab
1621 self._h_graph_exec, self._h_node, ¶ms,
1622 dst_owner, src_owner)
1624 @property
1625 def is_enabled(self) -> bool:
1626 """Whether this node is enabled in the executable graph."""
1627 return _get_executable_node_enabled( 1W
1628 self._h_graph_exec, self._h_node) 1W
1630 def enable(self) -> None:
1631 """Enable this node in the executable graph."""
1632 _set_executable_node_enabled( 1W
1633 self._h_graph_exec, self._h_node, True)
1635 def disable(self) -> None:
1636 """Disable this node in the executable graph."""
1637 _set_executable_node_enabled( 1W
1638 self._h_graph_exec, self._h_node, False)
1641cdef class ExecutableChildGraphNode(ExecutableGraphNode):
1642 """An executable child-graph-node view."""
1644 def update(self, GraphDefinition child not None: GraphDefinition) -> None:
1645 """Replace the embedded graph parameters for future launches."""
1646 GD_check_valid(child) 1UK
1647 cdef cydriver.CUgraphNodeParams params
1648 c_memset(¶ms, 0, sizeof(params)) 1UK
1649 params.type = cydriver.CU_GRAPH_NODE_TYPE_GRAPH 1UK
1650 params.graph.graph = as_cu(child._h_graph) 1UK
1651 _set_executable_node_params( 1UK
1652 self._h_graph_exec, self._h_node, ¶ms)
1655cdef class ExecutableEventRecordNode(ExecutableGraphNode):
1656 """An executable event-record-node view."""
1658 def update(self, Event event not None: Event) -> None:
1659 """Replace the event recorded by future launches."""
1660 Event_check_open(event) 14
1661 cdef OpaqueHandle event_owner = event._h_event 14
1662 cdef cydriver.CUgraphNodeParams params
1663 c_memset(¶ms, 0, sizeof(params)) 14
1664 params.type = cydriver.CU_GRAPH_NODE_TYPE_EVENT_RECORD 14
1665 params.eventRecord.event = as_cu(event._h_event) 14
1666 _set_executable_node_params( 14
1667 self._h_graph_exec, self._h_node, ¶ms, event_owner)
1670cdef class ExecutableEventWaitNode(ExecutableGraphNode):
1671 """An executable event-wait-node view."""
1673 def update(self, Event event not None: Event) -> None:
1674 """Replace the event waited on by future launches."""
1675 Event_check_open(event) 1R
1676 cdef OpaqueHandle event_owner = event._h_event 1R
1677 cdef cydriver.CUgraphNodeParams params
1678 c_memset(¶ms, 0, sizeof(params)) 1R
1679 params.type = cydriver.CU_GRAPH_NODE_TYPE_WAIT_EVENT 1R
1680 params.eventWait.event = as_cu(event._h_event) 1R
1681 _set_executable_node_params( 1R
1682 self._h_graph_exec, self._h_node, ¶ms, event_owner)
1685cdef class ExecutableHostCallbackNode(ExecutableGraphNode):
1686 """An executable host-callback-node view."""
1688 def update(self, fn, *, user_data=None) -> None:
1689 """Replace the callback and user-data binding for future launches.
1691 ``fn`` may be a Python callable, or a ctypes function pointer whose
1692 declared prototype matches ``CUhostFn`` (``void (*)(void*)``); a
1693 mismatched prototype raises ``TypeError``. ``user_data`` with a Python
1694 callable, or :data:`HOST_COPY_FN` without a packed record, raises
1695 ``ValueError``.
1697 .. warning::
1699 Callbacks must not call CUDA API functions. Doing so may deadlock
1700 or corrupt driver state.
1701 """
1702 cdef cydriver.CUhostFn c_fn
1703 cdef void* c_user_data
1704 cdef OpaqueHandle fn_owner
1705 cdef OpaqueHandle data_owner
1706 cdef cydriver.CUgraphNodeParams params
1708 _resolve_host_callback( 1VSTYOZ0
1709 fn, user_data, &c_fn, &c_user_data, &fn_owner, &data_owner)
1710 c_memset(¶ms, 0, sizeof(params)) 1VSTYOZ0
1711 params.type = cydriver.CU_GRAPH_NODE_TYPE_HOST 1VSTYOZ0
1712 params.host.fn = c_fn 1VSTYOZ0
1713 params.host.userData = c_user_data 1VSTYOZ0
1714 _set_executable_node_params( 1VSTYOZ0
1715 self._h_graph_exec, self._h_node, ¶ms,
1716 fn_owner, data_owner)
1719cdef ExecutableGraphNode create_executable_node_view(
1720 const GraphExecHandle& h_exec,
1721 GraphNode node):
1722 cdef type view_type
1723 if isinstance(node, KernelNode): 2U z V ~ } M JbKbu 3 W X SbK 4 R S T B C D G H I E F LbY O A a b J Z 0
1724 view_type = ExecutableKernelNode 2z ~ } M JbKb3 SbB C D A J
1725 elif isinstance(node, MemsetNode): 2U V u W X K 4 R S T G H I E F LbY O a b Z 0
1726 view_type = ExecutableMemsetNode 1XEF
1727 elif isinstance(node, MemcpyNode): 2U V u W K 4 R S T G H I LbY O a b Z 0
1728 view_type = ExecutableMemcpyNode 1uWGHIab
1729 elif isinstance(node, ChildGraphNode): 2U V K 4 R S T LbY O Z 0
1730 view_type = ExecutableChildGraphNode 1UK
1731 elif isinstance(node, EventRecordNode): 2V 4 R S T LbY O Z 0
1732 view_type = ExecutableEventRecordNode 14
1733 elif isinstance(node, EventWaitNode): 2V R S T LbY O Z 0
1734 view_type = ExecutableEventWaitNode 1R
1735 elif isinstance(node, HostCallbackNode): 2V S T LbY O Z 0
1736 view_type = ExecutableHostCallbackNode 1VSTYOZ0
1737 else:
1738 raise TypeError( 2Lb
1739 f"{type(node).__name__} does not support executable updates") 2Lb
1741 if as_cu(h_exec) == NULL: 2U z V ~ } M JbKbu 3 W X SbK 4 R S T B C D G H I E F Y O A a b J Z 0
1742 raise ValueError("executable graph has been closed")
1743 if as_cu(node._h_node) == NULL: 2U z V ~ } M JbKbu 3 W X SbK 4 R S T B C D G H I E F Y O A a b J Z 0
1744 raise ValueError("source graph node is no longer valid")
1746 cdef ExecutableGraphNode view = view_type.__new__(view_type) 2U z V ~ } M JbKbu 3 W X SbK 4 R S T B C D G H I E F Y O A a b J Z 0
1747 view._h_graph_exec = h_exec 2U z V ~ } M JbKbu 3 W X SbK 4 R S T B C D G H I E F Y O A a b J Z 0
1748 view._h_node = node._h_node 2U z V ~ } M JbKbu 3 W X SbK 4 R S T B C D G H I E F Y O A a b J Z 0
1749 return view 2U z V ~ } M JbKbu 3 W X SbK 4 R S T B C D G H I E F Y O A a b J Z 0