Coverage for cuda/core/graph/_subclasses.pyx: 84.79%
263 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-29 01:38 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-29 01:38 +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
12from cuda.bindings cimport cydriver
14from cuda.core._event cimport Event
15from cuda.core._launch_config cimport LaunchConfig
16from cuda.core._module cimport Kernel
17from cuda.core.graph._graph_definition cimport GraphCondition, GraphDefinition
18from cuda.core.graph._graph_node cimport GraphNode
19from cuda.core._resource_handles cimport (
20 EventHandle,
21 GraphHandle,
22 KernelHandle,
23 GraphNodeHandle,
24 as_cu,
25 as_intptr,
26 create_event_handle_ref,
27 create_child_graph_handle,
28 create_kernel_handle_ref,
29 graph_node_get_graph,
30)
31from cuda.core._utils.cuda_utils cimport HANDLE_RETURN
33from cuda.core.graph._host_callback cimport _is_py_host_trampoline
35from cuda.core._utils.cuda_utils import driver, handle_return
36from cuda.core.typing import GraphConditionalType
38__all__ = [
39 'AllocNode',
40 'ChildGraphNode',
41 'ConditionalNode',
42 'EmptyNode',
43 'EventRecordNode',
44 'EventWaitNode',
45 'FreeNode',
46 'HostCallbackNode',
47 'IfElseNode',
48 'IfNode',
49 'KernelNode',
50 'MemcpyNode',
51 'MemsetNode',
52 'SwitchNode',
53 'WhileNode',
54]
57cdef bint _has_cuGraphNodeGetParams = False
58cdef bint _version_checked = False
60cdef bint _check_node_get_params():
61 global _has_cuGraphNodeGetParams, _version_checked
62 if not _version_checked: 1dbeafcgho
63 from cuda.core._utils.version import binding_version, driver_version 1a
64 _has_cuGraphNodeGetParams = (
65 driver_version() >= (13, 2, 0) and binding_version() >= (13, 2, 0) 1a
66 )
67 _version_checked = True 1a
68 return _has_cuGraphNodeGetParams 1dbeafcgho
71cdef class EmptyNode(GraphNode):
72 """An empty (synchronization) node."""
74 @staticmethod
75 cdef EmptyNode _create_impl(GraphNodeHandle h_node):
76 cdef EmptyNode n = EmptyNode.__new__(EmptyNode) 2*d+d@ii j k l ,d-d.d/d' :dG ( ;d=d?d@d[d) ]d# * ^d[i+ _d, `d{d|d}d]i~dae^ibeifjfkflfmf_i}h`i{i|i}iufvfce- de. / ee: fe; ge= he? ieZ Zc0cWcOcjekeNb@ $ lemene[ H oe] pe^ v qe_ m I J x ` { | } p re~ seabtebbuecbdbveebwefbxegbyehbze0 1c2cXcPcAeBeObib% CeDeEejbK FekbGelbw Hembn L M y nbobpbqbq IerbJesbKetbYdN LeubMevbNewbOexbPeybQezbReAb
77 n._h_node = h_node 2*d+d@ii j k l ,d-d.d/d' :dG ( ;d=d?d@d[d) ]d# * ^d[i+ _d, `d{d|d}d]i~dae^ibeifjfkflfmf_i}h`i{i|i}iufvfce- de. / ee: fe; ge= he? ieZ Zc0cWcOcjekeNb@ $ lemene[ H oe] pe^ v qe_ m I J x ` { | } p re~ seabtebbuecbdbveebwefbxegbyehbze0 1c2cXcPcAeBeObib% CeDeEejbK FekbGelbw Hembn L M y nbobpbqbq IerbJesbKetbYdN LeubMevbNewbOexbPeybQezbReAb
78 return n 2*d+d@ii j k l ,d-d.d/d' :dG ( ;d=d?d@d[d) ]d# * ^d[i+ _d, `d{d|d}d]i~dae^ibeifjfkflfmf_i}h`i{i|i}iufvfce- de. / ee: fe; ge= he? ieZ Zc0cWcOcjekeNb@ $ lemene[ H oe] pe^ v qe_ m I J x ` { | } p re~ seabtebbuecbdbveebwefbxegbyehbze0 1c2cXcPcAeBeObib% CeDeEejbK FekbGelbw Hembn L M y nbobpbqbq IerbJesbKetbYdN LeubMevbNewbOexbPeybQezbReAb
80 def __repr__(self) -> str:
81 return f"<EmptyNode handle=0x{as_intptr(self._h_node):x}>" 2}hYd
84cdef class KernelNode(GraphNode):
85 """A kernel launch node.
87 Properties
88 ----------
89 grid : tuple of int
90 Grid dimensions (gridDimX, gridDimY, gridDimZ).
91 block : tuple of int
92 Block dimensions (blockDimX, blockDimY, blockDimZ).
93 shmem_size : int
94 Dynamic shared memory size in bytes.
95 kernel : Kernel
96 The kernel object for this launch node.
97 config : LaunchConfig
98 A LaunchConfig reconstructed from this node's parameters.
99 """
101 @staticmethod
102 cdef KernelNode _create_with_params(GraphNodeHandle h_node,
103 tuple grid, tuple block, unsigned int shmem_size,
104 KernelHandle h_kernel):
105 """Create from known params (called by launch() builder)."""
106 cdef KernelNode n = KernelNode.__new__(KernelNode) 2,cLg-c.c/cSeMgNgOgPgQgRgSg3cTe4cUe5cVe6cWe7cXe8cYe9cTg!cYc#c$cEbUgVgDfZdWgXgz ifjfkflfmft YgZeZg0e0gFb%c1e1g'c(cQc2e3e4e5e6e2g7e3g8e4gZ Nb9e5gO !e6g#e7g$e%e'eBb[c8g9gv E !g#g(e$gm r )e%g*e'g+e(g,e)gGb)c-e*g*c+cRc.e/e:e;e=e+g?e,g@e-g0 Ob[e.gP ]e/g^e:g_e`e{eCb]c;g=gw F ?g@g|e[gn s }e]g~e^gaf_g^cwfbf`gcf{gdf|gef}gff~ggfahhfbh
107 n._h_node = h_node 2,cLg-c.c/cSeMgNgOgPgQgRgSg3cTe4cUe5cVe6cWe7cXe8cYe9cTg!cYc#c$cEbUgVgDfZdWgXgz ifjfkflfmft YgZeZg0e0gFb%c1e1g'c(cQc2e3e4e5e6e2g7e3g8e4gZ Nb9e5gO !e6g#e7g$e%e'eBb[c8g9gv E !g#g(e$gm r )e%g*e'g+e(g,e)gGb)c-e*g*c+cRc.e/e:e;e=e+g?e,g@e-g0 Ob[e.gP ]e/g^e:g_e`e{eCb]c;g=gw F ?g@g|e[gn s }e]g~e^gaf_g^cwfbf`gcf{gdf|gef}gff~ggfahhfbh
108 n._grid = grid 2,cLg-c.c/cSeMgNgOgPgQgRgSg3cTe4cUe5cVe6cWe7cXe8cYe9cTg!cYc#c$cEbUgVgDfZdWgXgz ifjfkflfmft YgZeZg0e0gFb%c1e1g'c(cQc2e3e4e5e6e2g7e3g8e4gZ Nb9e5gO !e6g#e7g$e%e'eBb[c8g9gv E !g#g(e$gm r )e%g*e'g+e(g,e)gGb)c-e*g*c+cRc.e/e:e;e=e+g?e,g@e-g0 Ob[e.gP ]e/g^e:g_e`e{eCb]c;g=gw F ?g@g|e[gn s }e]g~e^gaf_g^cwfbf`gcf{gdf|gef}gff~ggfahhfbh
109 n._block = block 2,cLg-c.c/cSeMgNgOgPgQgRgSg3cTe4cUe5cVe6cWe7cXe8cYe9cTg!cYc#c$cEbUgVgDfZdWgXgz ifjfkflfmft YgZeZg0e0gFb%c1e1g'c(cQc2e3e4e5e6e2g7e3g8e4gZ Nb9e5gO !e6g#e7g$e%e'eBb[c8g9gv E !g#g(e$gm r )e%g*e'g+e(g,e)gGb)c-e*g*c+cRc.e/e:e;e=e+g?e,g@e-g0 Ob[e.gP ]e/g^e:g_e`e{eCb]c;g=gw F ?g@g|e[gn s }e]g~e^gaf_g^cwfbf`gcf{gdf|gef}gff~ggfahhfbh
110 n._shmem_size = shmem_size 2,cLg-c.c/cSeMgNgOgPgQgRgSg3cTe4cUe5cVe6cWe7cXe8cYe9cTg!cYc#c$cEbUgVgDfZdWgXgz ifjfkflfmft YgZeZg0e0gFb%c1e1g'c(cQc2e3e4e5e6e2g7e3g8e4gZ Nb9e5gO !e6g#e7g$e%e'eBb[c8g9gv E !g#g(e$gm r )e%g*e'g+e(g,e)gGb)c-e*g*c+cRc.e/e:e;e=e+g?e,g@e-g0 Ob[e.gP ]e/g^e:g_e`e{eCb]c;g=gw F ?g@g|e[gn s }e]g~e^gaf_g^cwfbf`gcf{gdf|gef}gff~ggfahhfbh
111 n._h_kernel = h_kernel 2,cLg-c.c/cSeMgNgOgPgQgRgSg3cTe4cUe5cVe6cWe7cXe8cYe9cTg!cYc#c$cEbUgVgDfZdWgXgz ifjfkflfmft YgZeZg0e0gFb%c1e1g'c(cQc2e3e4e5e6e2g7e3g8e4gZ Nb9e5gO !e6g#e7g$e%e'eBb[c8g9gv E !g#g(e$gm r )e%g*e'g+e(g,e)gGb)c-e*g*c+cRc.e/e:e;e=e+g?e,g@e-g0 Ob[e.gP ]e/g^e:g_e`e{eCb]c;g=gw F ?g@g|e[gn s }e]g~e^gaf_g^cwfbf`gcf{gdf|gef}gff~ggfahhfbh
112 return n 2,cLg-c.c/cSeMgNgOgPgQgRgSg3cTe4cUe5cVe6cWe7cXe8cYe9cTg!cYc#c$cEbUgVgDfZdWgXgz ifjfkflfmft YgZeZg0e0gFb%c1e1g'c(cQc2e3e4e5e6e2g7e3g8e4gZ Nb9e5gO !e6g#e7g$e%e'eBb[c8g9gv E !g#g(e$gm r )e%g*e'g+e(g,e)gGb)c-e*g*c+cRc.e/e:e;e=e+g?e,g@e-g0 Ob[e.gP ]e/g^e:g_e`e{eCb]c;g=gw F ?g@g|e[gn s }e]g~e^gaf_g^cwfbf`gcf{gdf|gef}gff~ggfahhfbh
114 @staticmethod
115 cdef KernelNode _create_from_driver(GraphNodeHandle h_node):
116 """Create by fetching params from the driver (called by _create factory)."""
117 cdef cydriver.CUgraphNode node = as_cu(h_node) 2,c-c.c/c3c!cYc#c$cEbz t
118 cdef cydriver.CUDA_KERNEL_NODE_PARAMS params
119 with nogil: 2,c-c.c/c3c!cYc#c$cEbz t
120 HANDLE_RETURN(cydriver.cuGraphKernelNodeGetParams(node, ¶ms)) 2,c-c.c/c3c!cYc#c$cEbz t
121 cdef KernelHandle h_kernel = create_kernel_handle_ref(params.kern) 2,c-c.c/c3c!cYc#c$cEbz t
122 return KernelNode._create_with_params( 2,c-c.c/c3c!cYc#c$cEbz t
123 h_node,
124 (params.gridDimX, params.gridDimY, params.gridDimZ), 2,c-c.c/c3c!cYc#c$cEbz t
125 (params.blockDimX, params.blockDimY, params.blockDimZ), 2,c-c.c/c3c!cYc#c$cEbz t
126 params.sharedMemBytes,
127 h_kernel)
129 def __repr__(self) -> str:
130 return (f"<KernelNode handle=0x{as_intptr(self._h_node):x}" 2wf
131 f" kernel=0x{as_intptr(self._h_kernel):x}>") 2wf
133 @property
134 def grid(self) -> tuple[int, int, int]:
135 """Grid dimensions as a 3-tuple (gridDimX, gridDimY, gridDimZ)."""
136 return self._grid 2ehQ
138 @property
139 def block(self) -> tuple[int, int, int]:
140 """Block dimensions as a 3-tuple (blockDimX, blockDimY, blockDimZ)."""
141 return self._block 2ehQ
143 @property
144 def shmem_size(self) -> int:
145 """Dynamic shared memory size in bytes."""
146 return self._shmem_size 2ehQ
148 @property
149 def kernel(self) -> Kernel:
150 """The Kernel object for this launch node."""
151 return Kernel._from_handle(self._h_kernel) 2ehQ DfZd
153 @property
154 def config(self) -> LaunchConfig:
155 """A LaunchConfig reconstructed from this node's grid, block, and shmem_size.
157 Note: cluster dimensions and is_cooperative are not preserved
158 by the CUDA driver's kernel node params, so they are not included.
159 """
160 return LaunchConfig(grid=self._grid, block=self._block, 2ehQ
161 shmem_size=self._shmem_size) 2ehQ
164cdef class AllocNode(GraphNode):
165 """A memory allocation node.
167 Properties
168 ----------
169 dptr : int
170 The device pointer for the allocation.
171 bytesize : int
172 The number of bytes allocated.
173 device_id : int
174 The device on which the allocation was made.
175 memory_type : GraphMemoryType | str
176 The type of memory allocated.
177 peer_access : tuple of int
178 Device IDs that have read-write access to this allocation.
179 """
181 @staticmethod
182 cdef AllocNode _create_with_params(GraphNodeHandle h_node,
183 cydriver.CUdeviceptr dptr, size_t bytesize,
184 int device_id, str memory_type, tuple peer_access):
185 """Create from known params (called by allocate() builder)."""
186 cdef AllocNode n = AllocNode.__new__(AllocNode) 2xfyf_cEfFfGfHf*dIf+dJfKf`c{c|c}c~ci j k l 1 2 3 4 LfMfNf,d-d.dOfPf/d0d1dad4c' PbQbRbSbX QfY Rf:dHb2dIb3dJbbdQ 5cG ( R TbS UbT VbU WbSf;dTf=dUfVfWf?dXf@dYfZf0f1f[d4d5dcd6c) XbYbZb0b1b2f2b3f3b]d4b6d5b7d6bdd7b7c# * 8b9b!b#b$b%b'b(b)b4f*b5f+b^d,b8d-b9d.bed/b8c+ :b;b=b?b@b[b]b^b6f7f_d!d#dfd9c, _b`b{b|b8f`d9f{d!f#f$f|d%f}d'f(f)f~d*fae+f,fbezf-fgdhd:c.fceid- }b/fdejd. ~bFb$d%dkd;c:f;f%c/ ac=f?f@feeld: bc[ffemd; cc]fgend= dc^fheod? ecieZ Zc0cWcOcjekeNb@ $ leme_fnepd[ fcO ScTcKbqdrdH 5 sdtd`foeud] gc{fpevd^ hcBbv E |fqewd_ icm I J x ` { | } r 6 7 V jckcp lcmc}frexd~ nc~fseydabocagtezdbbpcbgueAdcbqcGb'd(dBd=ccgdg)cdbrcegfgggveCdebschgweDdfbtcigxeEdgbucjgyeFdhbvcze0 1c2cXcPcAeBeObib% CeDekgEeGdjbwcP UcVcLbHdIdK 8 JdKdlgFeLdkbxcmgGeMdlbycCbw F ngHeNdmbzcn L M y nbobpbqbs 9 ! W AcBcq CcDcogIeOdrbEcpgJePdsbFcqgKeQdtbGcnfYd?cN DbrgLeRdubHcsgMeSdvbIctgNeTdwbJcugOeUdxbKcvgPeVdybLcwgQeWdzbMcxgReXdAbNc
187 n._h_node = h_node 2xfyf_cEfFfGfHf*dIf+dJfKf`c{c|c}c~ci j k l 1 2 3 4 LfMfNf,d-d.dOfPf/d0d1dad4c' PbQbRbSbX QfY Rf:dHb2dIb3dJbbdQ 5cG ( R TbS UbT VbU WbSf;dTf=dUfVfWf?dXf@dYfZf0f1f[d4d5dcd6c) XbYbZb0b1b2f2b3f3b]d4b6d5b7d6bdd7b7c# * 8b9b!b#b$b%b'b(b)b4f*b5f+b^d,b8d-b9d.bed/b8c+ :b;b=b?b@b[b]b^b6f7f_d!d#dfd9c, _b`b{b|b8f`d9f{d!f#f$f|d%f}d'f(f)f~d*fae+f,fbezf-fgdhd:c.fceid- }b/fdejd. ~bFb$d%dkd;c:f;f%c/ ac=f?f@feeld: bc[ffemd; cc]fgend= dc^fheod? ecieZ Zc0cWcOcjekeNb@ $ leme_fnepd[ fcO ScTcKbqdrdH 5 sdtd`foeud] gc{fpevd^ hcBbv E |fqewd_ icm I J x ` { | } r 6 7 V jckcp lcmc}frexd~ nc~fseydabocagtezdbbpcbgueAdcbqcGb'd(dBd=ccgdg)cdbrcegfgggveCdebschgweDdfbtcigxeEdgbucjgyeFdhbvcze0 1c2cXcPcAeBeObib% CeDekgEeGdjbwcP UcVcLbHdIdK 8 JdKdlgFeLdkbxcmgGeMdlbycCbw F ngHeNdmbzcn L M y nbobpbqbs 9 ! W AcBcq CcDcogIeOdrbEcpgJePdsbFcqgKeQdtbGcnfYd?cN DbrgLeRdubHcsgMeSdvbIctgNeTdwbJcugOeUdxbKcvgPeVdybLcwgQeWdzbMcxgReXdAbNc
188 n._dptr = dptr 2xfyf_cEfFfGfHf*dIf+dJfKf`c{c|c}c~ci j k l 1 2 3 4 LfMfNf,d-d.dOfPf/d0d1dad4c' PbQbRbSbX QfY Rf:dHb2dIb3dJbbdQ 5cG ( R TbS UbT VbU WbSf;dTf=dUfVfWf?dXf@dYfZf0f1f[d4d5dcd6c) XbYbZb0b1b2f2b3f3b]d4b6d5b7d6bdd7b7c# * 8b9b!b#b$b%b'b(b)b4f*b5f+b^d,b8d-b9d.bed/b8c+ :b;b=b?b@b[b]b^b6f7f_d!d#dfd9c, _b`b{b|b8f`d9f{d!f#f$f|d%f}d'f(f)f~d*fae+f,fbezf-fgdhd:c.fceid- }b/fdejd. ~bFb$d%dkd;c:f;f%c/ ac=f?f@feeld: bc[ffemd; cc]fgend= dc^fheod? ecieZ Zc0cWcOcjekeNb@ $ leme_fnepd[ fcO ScTcKbqdrdH 5 sdtd`foeud] gc{fpevd^ hcBbv E |fqewd_ icm I J x ` { | } r 6 7 V jckcp lcmc}frexd~ nc~fseydabocagtezdbbpcbgueAdcbqcGb'd(dBd=ccgdg)cdbrcegfgggveCdebschgweDdfbtcigxeEdgbucjgyeFdhbvcze0 1c2cXcPcAeBeObib% CeDekgEeGdjbwcP UcVcLbHdIdK 8 JdKdlgFeLdkbxcmgGeMdlbycCbw F ngHeNdmbzcn L M y nbobpbqbs 9 ! W AcBcq CcDcogIeOdrbEcpgJePdsbFcqgKeQdtbGcnfYd?cN DbrgLeRdubHcsgMeSdvbIctgNeTdwbJcugOeUdxbKcvgPeVdybLcwgQeWdzbMcxgReXdAbNc
189 n._bytesize = bytesize 2xfyf_cEfFfGfHf*dIf+dJfKf`c{c|c}c~ci j k l 1 2 3 4 LfMfNf,d-d.dOfPf/d0d1dad4c' PbQbRbSbX QfY Rf:dHb2dIb3dJbbdQ 5cG ( R TbS UbT VbU WbSf;dTf=dUfVfWf?dXf@dYfZf0f1f[d4d5dcd6c) XbYbZb0b1b2f2b3f3b]d4b6d5b7d6bdd7b7c# * 8b9b!b#b$b%b'b(b)b4f*b5f+b^d,b8d-b9d.bed/b8c+ :b;b=b?b@b[b]b^b6f7f_d!d#dfd9c, _b`b{b|b8f`d9f{d!f#f$f|d%f}d'f(f)f~d*fae+f,fbezf-fgdhd:c.fceid- }b/fdejd. ~bFb$d%dkd;c:f;f%c/ ac=f?f@feeld: bc[ffemd; cc]fgend= dc^fheod? ecieZ Zc0cWcOcjekeNb@ $ leme_fnepd[ fcO ScTcKbqdrdH 5 sdtd`foeud] gc{fpevd^ hcBbv E |fqewd_ icm I J x ` { | } r 6 7 V jckcp lcmc}frexd~ nc~fseydabocagtezdbbpcbgueAdcbqcGb'd(dBd=ccgdg)cdbrcegfgggveCdebschgweDdfbtcigxeEdgbucjgyeFdhbvcze0 1c2cXcPcAeBeObib% CeDekgEeGdjbwcP UcVcLbHdIdK 8 JdKdlgFeLdkbxcmgGeMdlbycCbw F ngHeNdmbzcn L M y nbobpbqbs 9 ! W AcBcq CcDcogIeOdrbEcpgJePdsbFcqgKeQdtbGcnfYd?cN DbrgLeRdubHcsgMeSdvbIctgNeTdwbJcugOeUdxbKcvgPeVdybLcwgQeWdzbMcxgReXdAbNc
190 n._device_id = device_id 2xfyf_cEfFfGfHf*dIf+dJfKf`c{c|c}c~ci j k l 1 2 3 4 LfMfNf,d-d.dOfPf/d0d1dad4c' PbQbRbSbX QfY Rf:dHb2dIb3dJbbdQ 5cG ( R TbS UbT VbU WbSf;dTf=dUfVfWf?dXf@dYfZf0f1f[d4d5dcd6c) XbYbZb0b1b2f2b3f3b]d4b6d5b7d6bdd7b7c# * 8b9b!b#b$b%b'b(b)b4f*b5f+b^d,b8d-b9d.bed/b8c+ :b;b=b?b@b[b]b^b6f7f_d!d#dfd9c, _b`b{b|b8f`d9f{d!f#f$f|d%f}d'f(f)f~d*fae+f,fbezf-fgdhd:c.fceid- }b/fdejd. ~bFb$d%dkd;c:f;f%c/ ac=f?f@feeld: bc[ffemd; cc]fgend= dc^fheod? ecieZ Zc0cWcOcjekeNb@ $ leme_fnepd[ fcO ScTcKbqdrdH 5 sdtd`foeud] gc{fpevd^ hcBbv E |fqewd_ icm I J x ` { | } r 6 7 V jckcp lcmc}frexd~ nc~fseydabocagtezdbbpcbgueAdcbqcGb'd(dBd=ccgdg)cdbrcegfgggveCdebschgweDdfbtcigxeEdgbucjgyeFdhbvcze0 1c2cXcPcAeBeObib% CeDekgEeGdjbwcP UcVcLbHdIdK 8 JdKdlgFeLdkbxcmgGeMdlbycCbw F ngHeNdmbzcn L M y nbobpbqbs 9 ! W AcBcq CcDcogIeOdrbEcpgJePdsbFcqgKeQdtbGcnfYd?cN DbrgLeRdubHcsgMeSdvbIctgNeTdwbJcugOeUdxbKcvgPeVdybLcwgQeWdzbMcxgReXdAbNc
191 n._memory_type = memory_type 2xfyf_cEfFfGfHf*dIf+dJfKf`c{c|c}c~ci j k l 1 2 3 4 LfMfNf,d-d.dOfPf/d0d1dad4c' PbQbRbSbX QfY Rf:dHb2dIb3dJbbdQ 5cG ( R TbS UbT VbU WbSf;dTf=dUfVfWf?dXf@dYfZf0f1f[d4d5dcd6c) XbYbZb0b1b2f2b3f3b]d4b6d5b7d6bdd7b7c# * 8b9b!b#b$b%b'b(b)b4f*b5f+b^d,b8d-b9d.bed/b8c+ :b;b=b?b@b[b]b^b6f7f_d!d#dfd9c, _b`b{b|b8f`d9f{d!f#f$f|d%f}d'f(f)f~d*fae+f,fbezf-fgdhd:c.fceid- }b/fdejd. ~bFb$d%dkd;c:f;f%c/ ac=f?f@feeld: bc[ffemd; cc]fgend= dc^fheod? ecieZ Zc0cWcOcjekeNb@ $ leme_fnepd[ fcO ScTcKbqdrdH 5 sdtd`foeud] gc{fpevd^ hcBbv E |fqewd_ icm I J x ` { | } r 6 7 V jckcp lcmc}frexd~ nc~fseydabocagtezdbbpcbgueAdcbqcGb'd(dBd=ccgdg)cdbrcegfgggveCdebschgweDdfbtcigxeEdgbucjgyeFdhbvcze0 1c2cXcPcAeBeObib% CeDekgEeGdjbwcP UcVcLbHdIdK 8 JdKdlgFeLdkbxcmgGeMdlbycCbw F ngHeNdmbzcn L M y nbobpbqbs 9 ! W AcBcq CcDcogIeOdrbEcpgJePdsbFcqgKeQdtbGcnfYd?cN DbrgLeRdubHcsgMeSdvbIctgNeTdwbJcugOeUdxbKcvgPeVdybLcwgQeWdzbMcxgReXdAbNc
192 n._peer_access = peer_access 2xfyf_cEfFfGfHf*dIf+dJfKf`c{c|c}c~ci j k l 1 2 3 4 LfMfNf,d-d.dOfPf/d0d1dad4c' PbQbRbSbX QfY Rf:dHb2dIb3dJbbdQ 5cG ( R TbS UbT VbU WbSf;dTf=dUfVfWf?dXf@dYfZf0f1f[d4d5dcd6c) XbYbZb0b1b2f2b3f3b]d4b6d5b7d6bdd7b7c# * 8b9b!b#b$b%b'b(b)b4f*b5f+b^d,b8d-b9d.bed/b8c+ :b;b=b?b@b[b]b^b6f7f_d!d#dfd9c, _b`b{b|b8f`d9f{d!f#f$f|d%f}d'f(f)f~d*fae+f,fbezf-fgdhd:c.fceid- }b/fdejd. ~bFb$d%dkd;c:f;f%c/ ac=f?f@feeld: bc[ffemd; cc]fgend= dc^fheod? ecieZ Zc0cWcOcjekeNb@ $ leme_fnepd[ fcO ScTcKbqdrdH 5 sdtd`foeud] gc{fpevd^ hcBbv E |fqewd_ icm I J x ` { | } r 6 7 V jckcp lcmc}frexd~ nc~fseydabocagtezdbbpcbgueAdcbqcGb'd(dBd=ccgdg)cdbrcegfgggveCdebschgweDdfbtcigxeEdgbucjgyeFdhbvcze0 1c2cXcPcAeBeObib% CeDekgEeGdjbwcP UcVcLbHdIdK 8 JdKdlgFeLdkbxcmgGeMdlbycCbw F ngHeNdmbzcn L M y nbobpbqbs 9 ! W AcBcq CcDcogIeOdrbEcpgJePdsbFcqgKeQdtbGcnfYd?cN DbrgLeRdubHcsgMeSdvbIctgNeTdwbJcugOeUdxbKcvgPeVdybLcwgQeWdzbMcxgReXdAbNc
193 return n 2xfyf_cEfFfGfHf*dIf+dJfKf`c{c|c}c~ci j k l 1 2 3 4 LfMfNf,d-d.dOfPf/d0d1dad4c' PbQbRbSbX QfY Rf:dHb2dIb3dJbbdQ 5cG ( R TbS UbT VbU WbSf;dTf=dUfVfWf?dXf@dYfZf0f1f[d4d5dcd6c) XbYbZb0b1b2f2b3f3b]d4b6d5b7d6bdd7b7c# * 8b9b!b#b$b%b'b(b)b4f*b5f+b^d,b8d-b9d.bed/b8c+ :b;b=b?b@b[b]b^b6f7f_d!d#dfd9c, _b`b{b|b8f`d9f{d!f#f$f|d%f}d'f(f)f~d*fae+f,fbezf-fgdhd:c.fceid- }b/fdejd. ~bFb$d%dkd;c:f;f%c/ ac=f?f@feeld: bc[ffemd; cc]fgend= dc^fheod? ecieZ Zc0cWcOcjekeNb@ $ leme_fnepd[ fcO ScTcKbqdrdH 5 sdtd`foeud] gc{fpevd^ hcBbv E |fqewd_ icm I J x ` { | } r 6 7 V jckcp lcmc}frexd~ nc~fseydabocagtezdbbpcbgueAdcbqcGb'd(dBd=ccgdg)cdbrcegfgggveCdebschgweDdfbtcigxeEdgbucjgyeFdhbvcze0 1c2cXcPcAeBeObib% CeDekgEeGdjbwcP UcVcLbHdIdK 8 JdKdlgFeLdkbxcmgGeMdlbycCbw F ngHeNdmbzcn L M y nbobpbqbs 9 ! W AcBcq CcDcogIeOdrbEcpgJePdsbFcqgKeQdtbGcnfYd?cN DbrgLeRdubHcsgMeSdvbIctgNeTdwbJcugOeUdxbKcvgPeVdybLcwgQeWdzbMcxgReXdAbNc
195 @staticmethod
196 cdef AllocNode _create_from_driver(GraphNodeHandle h_node):
197 """Create by fetching params from the driver (called by _create factory)."""
198 cdef cydriver.CUgraphNode node = as_cu(h_node) 2X Y HbIbJbQ G R S T U 1b2b3b4b5b6b7b# 8b!b$b'b)b*b+b,b-b.b/b:b=b@b]b
199 cdef cydriver.CUDA_MEM_ALLOC_NODE_PARAMS params
200 with nogil: 2X Y HbIbJbQ G R S T U 1b2b3b4b5b6b7b# 8b!b$b'b)b*b+b,b-b.b/b:b=b@b]b
201 HANDLE_RETURN(cydriver.cuGraphMemAllocNodeGetParams(node, ¶ms)) 2X Y HbIbJbQ G R S T U 1b2b3b4b5b6b7b# 8b!b$b'b)b*b+b,b-b.b/b:b=b@b]b
203 cdef str memory_type
204 if params.poolProps.allocType == cydriver.CUmemAllocationType.CU_MEM_ALLOCATION_TYPE_PINNED: 2X Y HbIbJbQ G R S T U 1b2b3b4b5b6b7b# 8b!b$b'b)b*b+b,b-b.b/b:b=b@b]b
205 if params.poolProps.location.type == cydriver.CUmemLocationType.CU_MEM_LOCATION_TYPE_HOST: 2X Y HbIbJbQ G R S T U 1b2b3b4b5b6b7b# 8b!b$b'b)b*b+b,b-b.b/b:b=b@b]b
206 memory_type = "host"
207 else:
208 memory_type = "device" 2X Y HbIbJbQ G R S T U 1b2b3b4b5b6b7b# 8b!b$b'b)b*b+b,b-b.b/b:b=b@b]b
209 else:
210 IF CUDA_CORE_BUILD_MAJOR >= 13:
211 if params.poolProps.allocType == cydriver.CUmemAllocationType.CU_MEM_ALLOCATION_TYPE_MANAGED:
212 memory_type = "managed"
213 else:
214 memory_type = "device"
215 ELSE:
216 memory_type = "device"
218 cdef list peer_ids = [] 2X Y HbIbJbQ G R S T U 1b2b3b4b5b6b7b# 8b!b$b'b)b*b+b,b-b.b/b:b=b@b]b
219 cdef size_t i
220 for i in range(params.accessDescCount): 2X Y HbIbJbQ G R S T U 1b2b3b4b5b6b7b# 8b!b$b'b)b*b+b,b-b.b/b:b=b@b]b
221 peer_ids.append(<int>params.accessDescs[i].location.id)
223 return AllocNode._create_with_params( 2X Y HbIbJbQ G R S T U 1b2b3b4b5b6b7b# 8b!b$b'b)b*b+b,b-b.b/b:b=b@b]b
224 h_node, params.dptr, params.bytesize,
225 <int>params.poolProps.location.id, memory_type, tuple(peer_ids)) 2X Y HbIbJbQ G R S T U 1b2b3b4b5b6b7b# 8b!b$b'b)b*b+b,b-b.b/b:b=b@b]b
227 def __repr__(self) -> str:
228 return (f"<AllocNode handle=0x{as_intptr(self._h_node):x}" 2nf
229 f" dptr=0x{self._dptr:x} size={self._bytesize}>") 2nf
231 @property
232 def dptr(self) -> int:
233 """The device pointer for the allocation."""
234 return self._dptr 2xfyf_c`c{c|c}c~ci j k l 1 2 3 4 @h[had' PbQbRbSbX Y bd( TbUbVbWbcd) XbYbZb0bdd* 9b#b%b(bed+ ;b?b[b^bfd, _b`b{b|bzfid- }bjd. ~bkd/ acld: bcmd; ccnd= dcod? ecWc@ $ pd[ fcO ScTcKbqdrdH 5 sdtdud] gcvd^ hcBbv E wd_ icm I J x ` { | } r 6 7 V jckcp lcmcxd~ ncydaboczdbbpcAdcbqcBddbrcCdebscDdfbtcEdgbucFdhbvcXcib% GdjbwcP UcVcLbHdIdK 8 JdKdLdkbxcMdlbycCbw F Ndmbzcn L M y nbobpbqbs 9 ! W AcBcq CcDcOdrbEcPdsbFcQdtbGc?cN DbRdubHcSdvbIcTdwbJcUdxbKcVdybLcWdzbMcXdAbNc
236 @property
237 def bytesize(self) -> int:
238 """The number of bytes allocated."""
239 return self._bytesize 2@h[hX Y
241 @property
242 def device_id(self) -> int:
243 """The device on which the allocation was made."""
244 return self._device_id 2@h[hX Y
246 @property
247 def memory_type(self) -> str:
248 """The type of memory: ``"device"``, ``"host"``, or ``"managed"``."""
249 return self._memory_type 2@h[hX Y
251 @property
252 def peer_access(self) -> tuple[int, ...]:
253 """Device IDs with read-write access to this allocation."""
254 return self._peer_access 2@h[hX Y
257cdef class FreeNode(GraphNode):
258 """A memory deallocation node.
260 Properties
261 ----------
262 dptr : int
263 The device pointer being freed.
264 """
266 @staticmethod
267 cdef FreeNode _create_with_params(GraphNodeHandle h_node,
268 cydriver.CUdeviceptr dptr):
269 """Create from known params (called by deallocate() builder)."""
270 cdef FreeNode n = FreeNode.__new__(FreeNode) 2_c`c{c|c}c~ci j k l 1 2 3 4 adbdcdddedfdidjdkdldmdndodWcpdO ScTcKbqdrdH 5 sdtdudvdBbwdxdydzdAdBdCdDdEdFdXcGdP UcVcLbHdIdK 8 JdKdLdMdCbNdOdPdQd?cRdSdTdUdVdWdXd
271 n._h_node = h_node 2_c`c{c|c}c~ci j k l 1 2 3 4 adbdcdddedfdidjdkdldmdndodWcpdO ScTcKbqdrdH 5 sdtdudvdBbwdxdydzdAdBdCdDdEdFdXcGdP UcVcLbHdIdK 8 JdKdLdMdCbNdOdPdQd?cRdSdTdUdVdWdXd
272 n._dptr = dptr 2_c`c{c|c}c~ci j k l 1 2 3 4 adbdcdddedfdidjdkdldmdndodWcpdO ScTcKbqdrdH 5 sdtdudvdBbwdxdydzdAdBdCdDdEdFdXcGdP UcVcLbHdIdK 8 JdKdLdMdCbNdOdPdQd?cRdSdTdUdVdWdXd
273 return n 2_c`c{c|c}c~ci j k l 1 2 3 4 adbdcdddedfdidjdkdldmdndodWcpdO ScTcKbqdrdH 5 sdtdudvdBbwdxdydzdAdBdCdDdEdFdXcGdP UcVcLbHdIdK 8 JdKdLdMdCbNdOdPdQd?cRdSdTdUdVdWdXd
275 @staticmethod
276 cdef FreeNode _create_from_driver(GraphNodeHandle h_node):
277 """Create by fetching params from the driver (called by _create factory)."""
278 cdef cydriver.CUgraphNode node = as_cu(h_node)
279 cdef cydriver.CUdeviceptr dptr
280 with nogil:
281 HANDLE_RETURN(cydriver.cuGraphMemFreeNodeGetParams(node, &dptr))
282 return FreeNode._create_with_params(h_node, dptr)
284 def __repr__(self) -> str:
285 return f"<FreeNode handle=0x{as_intptr(self._h_node):x} dptr=0x{self._dptr:x}>" 2?c
287 @property
288 def dptr(self) -> int:
289 """The device pointer being freed."""
290 return self._dptr 2fjJb
293cdef class MemsetNode(GraphNode):
294 """A memset node.
296 Properties
297 ----------
298 dptr : int
299 The destination device pointer.
300 value : int
301 The fill value.
302 element_size : int
303 Element size in bytes (1, 2, or 4).
304 width : int
305 Width of the row in elements.
306 height : int
307 Number of rows.
308 pitch : int
309 Pitch in bytes (unused if height is 1).
310 """
312 @staticmethod
313 cdef MemsetNode _create_with_params(GraphNodeHandle h_node,
314 cydriver.CUdeviceptr dptr, unsigned int value,
315 unsigned int element_size, size_t width,
316 size_t height, size_t pitch):
317 """Create from known params (called by memset() builder)."""
318 cdef MemsetNode n = MemsetNode.__new__(MemsetNode) 2i j k l 1 2 3 4 PbQbRbSbTbUbVbWbXbYbZb0b9b#b%b(b;b?b[b^b_b`b{b|bAfBfCft )d}b~bacbcccdcec$ fc5 gchcE icr 6 7 V jckcp lcmcncocpcqcrcsctcucvc% wc8 xcycF zcs 9 ! W AcBcq CcDcEcFcGcDbHcIcJcKcLcMcNc
319 n._h_node = h_node 2i j k l 1 2 3 4 PbQbRbSbTbUbVbWbXbYbZb0b9b#b%b(b;b?b[b^b_b`b{b|bAfBfCft )d}b~bacbcccdcec$ fc5 gchcE icr 6 7 V jckcp lcmcncocpcqcrcsctcucvc% wc8 xcycF zcs 9 ! W AcBcq CcDcEcFcGcDbHcIcJcKcLcMcNc
320 n._dptr = dptr 2i j k l 1 2 3 4 PbQbRbSbTbUbVbWbXbYbZb0b9b#b%b(b;b?b[b^b_b`b{b|bAfBfCft )d}b~bacbcccdcec$ fc5 gchcE icr 6 7 V jckcp lcmcncocpcqcrcsctcucvc% wc8 xcycF zcs 9 ! W AcBcq CcDcEcFcGcDbHcIcJcKcLcMcNc
321 n._value = value 2i j k l 1 2 3 4 PbQbRbSbTbUbVbWbXbYbZb0b9b#b%b(b;b?b[b^b_b`b{b|bAfBfCft )d}b~bacbcccdcec$ fc5 gchcE icr 6 7 V jckcp lcmcncocpcqcrcsctcucvc% wc8 xcycF zcs 9 ! W AcBcq CcDcEcFcGcDbHcIcJcKcLcMcNc
322 n._element_size = element_size 2i j k l 1 2 3 4 PbQbRbSbTbUbVbWbXbYbZb0b9b#b%b(b;b?b[b^b_b`b{b|bAfBfCft )d}b~bacbcccdcec$ fc5 gchcE icr 6 7 V jckcp lcmcncocpcqcrcsctcucvc% wc8 xcycF zcs 9 ! W AcBcq CcDcEcFcGcDbHcIcJcKcLcMcNc
323 n._width = width 2i j k l 1 2 3 4 PbQbRbSbTbUbVbWbXbYbZb0b9b#b%b(b;b?b[b^b_b`b{b|bAfBfCft )d}b~bacbcccdcec$ fc5 gchcE icr 6 7 V jckcp lcmcncocpcqcrcsctcucvc% wc8 xcycF zcs 9 ! W AcBcq CcDcEcFcGcDbHcIcJcKcLcMcNc
324 n._height = height 2i j k l 1 2 3 4 PbQbRbSbTbUbVbWbXbYbZb0b9b#b%b(b;b?b[b^b_b`b{b|bAfBfCft )d}b~bacbcccdcec$ fc5 gchcE icr 6 7 V jckcp lcmcncocpcqcrcsctcucvc% wc8 xcycF zcs 9 ! W AcBcq CcDcEcFcGcDbHcIcJcKcLcMcNc
325 n._pitch = pitch 2i j k l 1 2 3 4 PbQbRbSbTbUbVbWbXbYbZb0b9b#b%b(b;b?b[b^b_b`b{b|bAfBfCft )d}b~bacbcccdcec$ fc5 gchcE icr 6 7 V jckcp lcmcncocpcqcrcsctcucvc% wc8 xcycF zcs 9 ! W AcBcq CcDcEcFcGcDbHcIcJcKcLcMcNc
326 return n 2i j k l 1 2 3 4 PbQbRbSbTbUbVbWbXbYbZb0b9b#b%b(b;b?b[b^b_b`b{b|bAfBfCft )d}b~bacbcccdcec$ fc5 gchcE icr 6 7 V jckcp lcmcncocpcqcrcsctcucvc% wc8 xcycF zcs 9 ! W AcBcq CcDcEcFcGcDbHcIcJcKcLcMcNc
328 @staticmethod
329 cdef MemsetNode _create_from_driver(GraphNodeHandle h_node):
330 """Create by fetching params from the driver (called by _create factory)."""
331 cdef cydriver.CUgraphNode node = as_cu(h_node) 1t
332 cdef cydriver.CUDA_MEMSET_NODE_PARAMS params
333 with nogil: 1t
334 HANDLE_RETURN(cydriver.cuGraphMemsetNodeGetParams(node, ¶ms)) 1t
335 return MemsetNode._create_with_params( 1t
336 h_node, params.dst, params.value,
337 params.elementSize, params.width, params.height, params.pitch) 1t
339 def __repr__(self) -> str:
340 return (f"<MemsetNode handle=0x{as_intptr(self._h_node):x}" 2Db
341 f" dptr=0x{self._dptr:x} value={self._value}>") 2Db
343 @property
344 def dptr(self) -> int:
345 """The destination device pointer."""
346 return self._dptr 2fhghhhihR S T U )d
348 @property
349 def value(self) -> int:
350 """The fill value."""
351 return self._value 2fhghhhihR S T U )d
353 @property
354 def element_size(self) -> int:
355 """Element size in bytes (1, 2, or 4)."""
356 return self._element_size 2fhghhhihR S T U
358 @property
359 def width(self) -> int:
360 """Width of the row in elements."""
361 return self._width 2fhghhhihR S T U )d
363 @property
364 def height(self) -> int:
365 """Number of rows."""
366 return self._height 2fhghhhihR S T U
368 @property
369 def pitch(self) -> int:
370 """Pitch in bytes (unused if height is 1)."""
371 return self._pitch 2fhghhhihR S T U
374cdef class MemcpyNode(GraphNode):
375 """A memcpy node.
377 Properties
378 ----------
379 dst : int
380 The destination pointer.
381 src : int
382 The source pointer.
383 size : int
384 The number of bytes copied.
385 """
387 @staticmethod
388 cdef MemcpyNode _create_with_params(GraphNodeHandle h_node,
389 cydriver.CUdeviceptr dst, cydriver.CUdeviceptr src,
390 size_t size, cydriver.CUmemorytype dst_type,
391 cydriver.CUmemorytype src_type):
392 """Create from known params (called by memcpy() builder)."""
393 cdef MemcpyNode n = MemcpyNode.__new__(MemcpyNode) 2i j k l ' ( ) * + , ygzg@cAgBgCgDgEgFg- . / : ; = ? @ [ H ] ^ v _ m I J x ` { | } p ~ abbbcbdbebfbgbhbibjbK kblbw mbn L M y nbobpbqbq rbsbtbN ubvbwbxbybzbAb
394 n._h_node = h_node 2i j k l ' ( ) * + , ygzg@cAgBgCgDgEgFg- . / : ; = ? @ [ H ] ^ v _ m I J x ` { | } p ~ abbbcbdbebfbgbhbibjbK kblbw mbn L M y nbobpbqbq rbsbtbN ubvbwbxbybzbAb
395 n._dst = dst 2i j k l ' ( ) * + , ygzg@cAgBgCgDgEgFg- . / : ; = ? @ [ H ] ^ v _ m I J x ` { | } p ~ abbbcbdbebfbgbhbibjbK kblbw mbn L M y nbobpbqbq rbsbtbN ubvbwbxbybzbAb
396 n._src = src 2i j k l ' ( ) * + , ygzg@cAgBgCgDgEgFg- . / : ; = ? @ [ H ] ^ v _ m I J x ` { | } p ~ abbbcbdbebfbgbhbibjbK kblbw mbn L M y nbobpbqbq rbsbtbN ubvbwbxbybzbAb
397 n._size = size 2i j k l ' ( ) * + , ygzg@cAgBgCgDgEgFg- . / : ; = ? @ [ H ] ^ v _ m I J x ` { | } p ~ abbbcbdbebfbgbhbibjbK kblbw mbn L M y nbobpbqbq rbsbtbN ubvbwbxbybzbAb
398 n._dst_type = dst_type 2i j k l ' ( ) * + , ygzg@cAgBgCgDgEgFg- . / : ; = ? @ [ H ] ^ v _ m I J x ` { | } p ~ abbbcbdbebfbgbhbibjbK kblbw mbn L M y nbobpbqbq rbsbtbN ubvbwbxbybzbAb
399 n._src_type = src_type 2i j k l ' ( ) * + , ygzg@cAgBgCgDgEgFg- . / : ; = ? @ [ H ] ^ v _ m I J x ` { | } p ~ abbbcbdbebfbgbhbibjbK kblbw mbn L M y nbobpbqbq rbsbtbN ubvbwbxbybzbAb
400 return n 2i j k l ' ( ) * + , ygzg@cAgBgCgDgEgFg- . / : ; = ? @ [ H ] ^ v _ m I J x ` { | } p ~ abbbcbdbebfbgbhbibjbK kblbw mbn L M y nbobpbqbq rbsbtbN ubvbwbxbybzbAb
402 @staticmethod
403 cdef MemcpyNode _create_from_driver(GraphNodeHandle h_node):
404 """Create by fetching params from the driver (called by _create factory)."""
405 cdef cydriver.CUgraphNode node = as_cu(h_node)
406 cdef cydriver.CUDA_MEMCPY3D params
407 with nogil:
408 HANDLE_RETURN(cydriver.cuGraphMemcpyNodeGetParams(node, ¶ms))
410 cdef cydriver.CUdeviceptr dst
411 cdef cydriver.CUdeviceptr src
412 if params.dstMemoryType == cydriver.CU_MEMORYTYPE_HOST:
413 dst = <cydriver.CUdeviceptr><uintptr_t>params.dstHost
414 else:
415 dst = params.dstDevice
416 if params.srcMemoryType == cydriver.CU_MEMORYTYPE_HOST:
417 src = <cydriver.CUdeviceptr><uintptr_t>params.srcHost
418 else:
419 src = params.srcDevice
421 return MemcpyNode._create_with_params(
422 h_node, dst, src, params.WidthInBytes,
423 params.dstMemoryType, params.srcMemoryType)
425 def __repr__(self) -> str:
426 cdef str dt = "H" if self._dst_type == cydriver.CU_MEMORYTYPE_HOST else "D" 1N
427 cdef str st = "H" if self._src_type == cydriver.CU_MEMORYTYPE_HOST else "D" 1N
428 return (f"<MemcpyNode handle=0x{as_intptr(self._h_node):x}" 1N
429 f" dst=0x{self._dst:x}({dt}) src=0x{self._src:x}({st}) size={self._size}>") 1N
431 @property
432 def dst(self) -> int:
433 """The destination pointer."""
434 return self._dst 2~iG
436 @property
437 def src(self) -> int:
438 """The source pointer."""
439 return self._src 2~iG
441 @property
442 def size(self) -> int:
443 """The number of bytes copied."""
444 return self._size 2~iG
447cdef class ChildGraphNode(GraphNode):
448 """A child graph node.
450 Properties
451 ----------
452 child_graph : GraphDefinition
453 The embedded graph definition (non-owning wrapper).
454 """
456 @staticmethod
457 cdef ChildGraphNode _create_with_params(GraphNodeHandle h_node,
458 GraphHandle h_child_graph):
459 """Create from known params (called by embed() builder)."""
460 cdef ChildGraphNode n = ChildGraphNode.__new__(ChildGraphNode) 2SeTeUeVeWeXeYeA Eb]hB ofC z MbD Ze0eFb1e'c(cQc2e3e4e5e6e7e8eZ 9eO !e#e$e(em r )e*e+e,eGb-e*c+cRc.e/e:e;e=e?e@e0 [eP ]e^e_e|en s }e~eaf^cbfcfdfefffgfhf
461 n._h_node = h_node 2SeTeUeVeWeXeYeA Eb]hB ofC z MbD Ze0eFb1e'c(cQc2e3e4e5e6e7e8eZ 9eO !e#e$e(em r )e*e+e,eGb-e*c+cRc.e/e:e;e=e?e@e0 [eP ]e^e_e|en s }e~eaf^cbfcfdfefffgfhf
462 n._h_child_graph = h_child_graph 2SeTeUeVeWeXeYeA Eb]hB ofC z MbD Ze0eFb1e'c(cQc2e3e4e5e6e7e8eZ 9eO !e#e$e(em r )e*e+e,eGb-e*c+cRc.e/e:e;e=e?e@e0 [eP ]e^e_e|en s }e~eaf^cbfcfdfefffgfhf
463 return n 2SeTeUeVeWeXeYeA Eb]hB ofC z MbD Ze0eFb1e'c(cQc2e3e4e5e6e7e8eZ 9eO !e#e$e(em r )e*e+e,eGb-e*c+cRc.e/e:e;e=e?e@e0 [eP ]e^e_e|en s }e~eaf^cbfcfdfefffgfhf
465 @staticmethod
466 cdef ChildGraphNode _create_from_driver(GraphNodeHandle h_node):
467 """Create by fetching params from the driver (called by _create factory)."""
468 cdef cydriver.CUgraphNode node = as_cu(h_node) 1ABCzD
469 cdef cydriver.CUgraph child_graph = NULL 1ABCzD
470 with nogil: 1ABCzD
471 HANDLE_RETURN(cydriver.cuGraphChildGraphNodeGetGraph(node, &child_graph)) 1ABCzD
472 cdef GraphHandle h_graph = graph_node_get_graph(h_node) 1ABCzD
473 cdef GraphHandle h_child = create_child_graph_handle( 1ABCzD
474 child_graph, h_graph, node)
475 return ChildGraphNode._create_with_params(h_node, h_child) 1ABCzD
477 def __repr__(self) -> str:
478 return (f"<ChildGraphNode handle=0x{as_intptr(self._h_node):x}" 2^c
479 f" child=0x{as_intptr(self._h_child_graph):x}>") 2^c
481 @property
482 def child_graph(self) -> GraphDefinition:
483 """The embedded graph definition (non-owning wrapper)."""
484 return GraphDefinition._from_handle(self._h_child_graph) 23cgjA Eb]hB C z MbD
487cdef class EventRecordNode(GraphNode):
488 """An event record node.
490 Properties
491 ----------
492 event : Event
493 The event being recorded.
494 """
496 @staticmethod
497 cdef EventRecordNode _create_with_params(GraphNodeHandle h_node,
498 EventHandle h_event):
499 """Create from known params (called by record() builder)."""
500 cdef EventRecordNode n = EventRecordNode.__new__(EventRecordNode) 2Gg0d2d4d6d8d!d^hgd_hHgIgZd~hai$dbi'ccidieiZcfiJgpfgihiiijiSckili%emiI 6 nioipiqi'dri*csitiui1cviKgqfwixiyiziUcAiBi`eCiL 9 DiEiFijhGiHiIiJiKiLiMi
501 n._h_node = h_node 2Gg0d2d4d6d8d!d^hgd_hHgIgZd~hai$dbi'ccidieiZcfiJgpfgihiiijiSckili%emiI 6 nioipiqi'dri*csitiui1cviKgqfwixiyiziUcAiBi`eCiL 9 DiEiFijhGiHiIiJiKiLiMi
502 n._h_event = h_event 2Gg0d2d4d6d8d!d^hgd_hHgIgZd~hai$dbi'ccidieiZcfiJgpfgihiiijiSckili%emiI 6 nioipiqi'dri*csitiui1cviKgqfwixiyiziUcAiBi`eCiL 9 DiEiFijhGiHiIiJiKiLiMi
503 return n 2Gg0d2d4d6d8d!d^hgd_hHgIgZd~hai$dbi'ccidieiZcfiJgpfgihiiijiSckili%emiI 6 nioipiqi'dri*csitiui1cviKgqfwixiyiziUcAiBi`eCiL 9 DiEiFijhGiHiIiJiKiLiMi
505 @staticmethod
506 cdef EventRecordNode _create_from_driver(GraphNodeHandle h_node):
507 """Create by fetching params from the driver (called by _create factory)."""
508 cdef cydriver.CUgraphNode node = as_cu(h_node)
509 cdef cydriver.CUevent event
510 with nogil:
511 HANDLE_RETURN(cydriver.cuGraphEventRecordNodeGetEvent(node, &event))
512 cdef EventHandle h_event = create_event_handle_ref(event)
513 return EventRecordNode._create_with_params(h_node, h_event)
515 def __repr__(self) -> str:
516 return (f"<EventRecordNode handle=0x{as_intptr(self._h_node):x}" 2jh
517 f" event=0x{as_intptr(self._h_event):x}>") 2jh
519 @property
520 def event(self) -> Event:
521 """The event being recorded."""
522 return Event._from_handle(self._h_event) 2hjHb^hgd_h
525cdef class EventWaitNode(GraphNode):
526 """An event wait node.
528 Properties
529 ----------
530 event : Event
531 The event being waited on.
532 """
534 @staticmethod
535 cdef EventWaitNode _create_with_params(GraphNodeHandle h_node,
536 EventHandle h_event):
537 """Create from known params (called by wait() builder)."""
538 cdef EventWaitNode n = EventWaitNode.__new__(EventWaitNode) 2Gg1d3d5d7d9d#dHgIghd`hNiOi%dPi(cQiRiSi0cTiJgrfUiViWiXiTcYiZi'e0iJ 7 1i2i3i4i(d5i+c6i7i8i2c9iKgsf!i#i$i%iVc'i(i{e)iM ! *i+i,ikh-i.i/i:i;i=i?i
539 n._h_node = h_node 2Gg1d3d5d7d9d#dHgIghd`hNiOi%dPi(cQiRiSi0cTiJgrfUiViWiXiTcYiZi'e0iJ 7 1i2i3i4i(d5i+c6i7i8i2c9iKgsf!i#i$i%iVc'i(i{e)iM ! *i+i,ikh-i.i/i:i;i=i?i
540 n._h_event = h_event 2Gg1d3d5d7d9d#dHgIghd`hNiOi%dPi(cQiRiSi0cTiJgrfUiViWiXiTcYiZi'e0iJ 7 1i2i3i4i(d5i+c6i7i8i2c9iKgsf!i#i$i%iVc'i(i{e)iM ! *i+i,ikh-i.i/i:i;i=i?i
541 return n 2Gg1d3d5d7d9d#dHgIghd`hNiOi%dPi(cQiRiSi0cTiJgrfUiViWiXiTcYiZi'e0iJ 7 1i2i3i4i(d5i+c6i7i8i2c9iKgsf!i#i$i%iVc'i(i{e)iM ! *i+i,ikh-i.i/i:i;i=i?i
543 @staticmethod
544 cdef EventWaitNode _create_from_driver(GraphNodeHandle h_node):
545 """Create by fetching params from the driver (called by _create factory)."""
546 cdef cydriver.CUgraphNode node = as_cu(h_node)
547 cdef cydriver.CUevent event
548 with nogil:
549 HANDLE_RETURN(cydriver.cuGraphEventWaitNodeGetEvent(node, &event))
550 cdef EventHandle h_event = create_event_handle_ref(event)
551 return EventWaitNode._create_with_params(h_node, h_event)
553 def __repr__(self) -> str:
554 return (f"<EventWaitNode handle=0x{as_intptr(self._h_node):x}" 2kh
555 f" event=0x{as_intptr(self._h_event):x}>") 2kh
557 @property
558 def event(self) -> Event:
559 """The event being waited on."""
560 return Event._from_handle(self._h_event) 2ijIbhd`h
563cdef class HostCallbackNode(GraphNode):
564 """A host callback node.
566 Properties
567 ----------
568 callback : callable or None
569 The Python callable (None for ctypes function pointer callbacks).
570 """
572 @staticmethod
573 cdef HostCallbackNode _create_with_params(GraphNodeHandle h_node,
574 object callable_obj, cydriver.CUhostFn fn,
575 void* user_data):
576 """Create from known params (called by callback() builder)."""
577 cdef HostCallbackNode n = HostCallbackNode.__new__(HostCallbackNode) 2lhmhnhohphqhrhshthuhvhwhxhyhzhAhA BhChDhEhB ofd b e a f c g h @cC FhMbGhD Hh:cufvfIhJhKh;cLhQcMhNhOhOcPhpfrfKbQhRhShThUhVh[cWhx V XhYhZh0h=c1hRc2h3h4hPc5hqfsfLb6h7h8h9h!h#h]c$hy W %h'h(htf)h*h+h,h-h.h/h
578 n._h_node = h_node 2lhmhnhohphqhrhshthuhvhwhxhyhzhAhA BhChDhEhB ofd b e a f c g h @cC FhMbGhD Hh:cufvfIhJhKh;cLhQcMhNhOhOcPhpfrfKbQhRhShThUhVh[cWhx V XhYhZh0h=c1hRc2h3h4hPc5hqfsfLb6h7h8h9h!h#h]c$hy W %h'h(htf)h*h+h,h-h.h/h
579 n._callable = callable_obj 2lhmhnhohphqhrhshthuhvhwhxhyhzhAhA BhChDhEhB ofd b e a f c g h @cC FhMbGhD Hh:cufvfIhJhKh;cLhQcMhNhOhOcPhpfrfKbQhRhShThUhVh[cWhx V XhYhZh0h=c1hRc2h3h4hPc5hqfsfLb6h7h8h9h!h#h]c$hy W %h'h(htf)h*h+h,h-h.h/h
580 n._fn = fn 2lhmhnhohphqhrhshthuhvhwhxhyhzhAhA BhChDhEhB ofd b e a f c g h @cC FhMbGhD Hh:cufvfIhJhKh;cLhQcMhNhOhOcPhpfrfKbQhRhShThUhVh[cWhx V XhYhZh0h=c1hRc2h3h4hPc5hqfsfLb6h7h8h9h!h#h]c$hy W %h'h(htf)h*h+h,h-h.h/h
581 n._user_data = user_data 2lhmhnhohphqhrhshthuhvhwhxhyhzhAhA BhChDhEhB ofd b e a f c g h @cC FhMbGhD Hh:cufvfIhJhKh;cLhQcMhNhOhOcPhpfrfKbQhRhShThUhVh[cWhx V XhYhZh0h=c1hRc2h3h4hPc5hqfsfLb6h7h8h9h!h#h]c$hy W %h'h(htf)h*h+h,h-h.h/h
582 return n 2lhmhnhohphqhrhshthuhvhwhxhyhzhAhA BhChDhEhB ofd b e a f c g h @cC FhMbGhD Hh:cufvfIhJhKh;cLhQcMhNhOhOcPhpfrfKbQhRhShThUhVh[cWhx V XhYhZh0h=c1hRc2h3h4hPc5hqfsfLb6h7h8h9h!h#h]c$hy W %h'h(htf)h*h+h,h-h.h/h
584 @staticmethod
585 cdef HostCallbackNode _create_from_driver(GraphNodeHandle h_node):
586 """Create by fetching params from the driver (called by _create factory)."""
587 cdef cydriver.CUgraphNode node = as_cu(h_node) 2A B C MbD
588 cdef cydriver.CUDA_HOST_NODE_PARAMS params
589 with nogil: 2A B C MbD
590 HANDLE_RETURN(cydriver.cuGraphHostNodeGetParams(node, ¶ms)) 2A B C MbD
592 cdef object callable_obj = None 2A B C MbD
593 if _is_py_host_trampoline(params.fn): 2A B C MbD
594 callable_obj = <object>params.userData 2A B C MbD
596 return HostCallbackNode._create_with_params( 2A B C MbD
597 h_node, callable_obj, params.fn, params.userData) 2A B C MbD
599 def __repr__(self) -> str:
600 if self._callable is not None: 2tf
601 name = getattr(self._callable, '__name__', '?') 2tf
602 return (f"<HostCallbackNode handle=0x{as_intptr(self._h_node):x}" 2tf
603 f" callback={name}>") 2tf
604 return (f"<HostCallbackNode handle=0x{as_intptr(self._h_node):x}"
605 f" cfunc=0x{<uintptr_t>self._fn:x}>")
607 @property
608 def callback(self):
609 """The Python callable, or None for ctypes function pointer callbacks."""
610 return self._callable 2jjkj
613cdef class ConditionalNode(GraphNode):
614 """Base class for conditional nodes.
616 When created via builder methods (if_then, if_else, while_loop, switch),
617 a specific subclass (IfNode, IfElseNode, WhileNode, SwitchNode) is
618 returned. When reconstructed from the driver on CUDA 13.2+, the
619 correct subclass is determined via cuGraphNodeGetParams. On older
620 drivers, this base class is used as a fallback.
622 Properties
623 ----------
624 condition : GraphCondition or None
625 The condition variable controlling execution (None pre-13.2).
626 cond_type : str or None
627 The conditional type ("if", "while", or "switch"; None pre-13.2).
628 branches : tuple of GraphDefinition
629 The body graphs for each branch (empty pre-13.2).
630 """
632 @staticmethod
633 cdef ConditionalNode _create_from_driver(GraphNodeHandle h_node):
634 cdef ConditionalNode n
635 if not _check_node_get_params(): 1dbeafcgho
636 n = ConditionalNode.__new__(ConditionalNode)
637 n._h_node = h_node
638 n._condition = None
639 n._cond_type = cydriver.CU_GRAPH_COND_TYPE_IF
640 n._branches = ()
641 return n
643 cdef cydriver.CUgraphNode node = as_cu(h_node) 1dbeafcgho
644 params = handle_return(driver.cuGraphNodeGetParams( 1dbeafcgho
645 <uintptr_t>node)) 1dbeafcgho
646 cond_params = params.conditional 1dbeafcgho
647 cdef int cond_type_int = int(cond_params.type) 1dbeafcgho
648 cdef unsigned int size = int(cond_params.size) 1dbeafcgho
650 cdef GraphCondition condition = GraphCondition.__new__(GraphCondition) 1dbeafcgho
651 condition._c_handle = <cydriver.CUgraphConditionalHandle>( 1dbeafcgho
652 <unsigned long long>int(cond_params.handle)) 1dbeafcgho
654 cdef GraphHandle h_graph = graph_node_get_graph(h_node) 1dbeafcgho
655 cdef list branch_list = [] 1dbeafcgho
656 cdef unsigned int i
657 cdef GraphHandle h_branch
658 if cond_params.phGraph_out is not None: 1dbeafcgho
659 for i in range(size): 1dbeafcgho
660 h_branch = create_child_graph_handle( 1dbeafcgho
661 <cydriver.CUgraph><uintptr_t>int(cond_params.phGraph_out[i]), 1dbeafcgho
662 h_graph, node)
663 branch_list.append(GraphDefinition._from_handle(h_branch)) 1dbeafcgho
664 cdef tuple branches = tuple(branch_list) 1dbeafcgho
666 cdef type cls
667 if cond_type_int == <int>cydriver.CU_GRAPH_COND_TYPE_IF: 1dbeafcgho
668 if size == 1: 1dbfc
669 cls = IfNode 1df
670 else:
671 cls = IfElseNode 1bc
672 elif cond_type_int == <int>cydriver.CU_GRAPH_COND_TYPE_WHILE: 1eagho
673 cls = WhileNode 1aho
674 else:
675 cls = SwitchNode 1eg
677 n = cls.__new__(cls) 1dbeafcgho
678 n._h_node = h_node 1dbeafcgho
679 n._condition = condition 1dbeafcgho
680 n._cond_type = <cydriver.CUgraphConditionalNodeType>cond_type_int 1dbeafcgho
681 n._branches = branches 1dbeafcgho
682 return n 1dbeafcgho
684 def __repr__(self) -> str:
685 return f"<ConditionalNode handle=0x{as_intptr(self._h_node):x}>"
687 @property
688 def condition(self) -> GraphCondition | None:
689 """The condition variable controlling execution."""
690 return self._condition 2ch:h{h;hdh=h|h?h
692 @property
693 def cond_type(self) -> GraphConditionalType | None:
694 """The conditional type: GraphConditionalType.IF, .WHILE, or .SWITCH
696 Returns None when reconstructed from the driver pre-CUDA 13.2,
697 as the conditional type cannot be determined.
698 """
699 if self._condition is None: 2ch:h{h;hdh=h|h?h
700 return None
701 if self._cond_type == cydriver.CU_GRAPH_COND_TYPE_IF: 2ch:h{h;hdh=h|h?h
702 return GraphConditionalType("if") 2ch:hdh=h
703 elif self._cond_type == cydriver.CU_GRAPH_COND_TYPE_WHILE:
704 return GraphConditionalType("while") 2;h?h
705 else:
706 return GraphConditionalType("switch") 2{h|h
708 @property
709 def branches(self) -> tuple[GraphDefinition, ...]:
710 """The body graphs for each branch as a tuple of GraphDefinition.
712 Returns an empty tuple when reconstructed from the driver
713 pre-CUDA 13.2.
714 """
715 return self._branches 2ch:h{h;hdh=h|h?hlj#ce g o
718cdef class IfNode(ConditionalNode):
719 """An if-conditional node."""
721 def __repr__(self) -> str:
722 return (f"<IfNode handle=0x{as_intptr(self._h_node):x}" 2aj
723 f" condition=0x{<unsigned long long>self._condition._c_handle:x}>") 2aj
725 @property
726 def then(self) -> GraphDefinition:
727 """The 'then' branch graph."""
728 return self._branches[0] 2:h=hmj!cd f
731cdef class IfElseNode(ConditionalNode):
732 """An if-else conditional node."""
734 def __repr__(self) -> str:
735 return (f"<IfElseNode handle=0x{as_intptr(self._h_node):x}" 2bj
736 f" condition=0x{<unsigned long long>self._condition._c_handle:x}>") 2bj
738 @property
739 def then(self) -> GraphDefinition:
740 """The ``then`` branch graph (executed when condition is non-zero)."""
741 return self._branches[0] 2chdhcjYcb c
743 @property
744 def else_(self) -> GraphDefinition:
745 """The ``else`` branch graph (executed when condition is zero)."""
746 return self._branches[1] 2chdhcjYcb c
749cdef class WhileNode(ConditionalNode):
750 """A while-loop conditional node."""
752 def __repr__(self) -> str:
753 return (f"<WhileNode handle=0x{as_intptr(self._h_node):x}" 2dj
754 f" condition=0x{<unsigned long long>self._condition._c_handle:x}>") 2dj
756 @property
757 def body(self) -> GraphDefinition:
758 """The loop body graph."""
759 return self._branches[0] 2;h?hnj$ca h
762cdef class SwitchNode(ConditionalNode):
763 """A switch conditional node."""
765 def __repr__(self) -> str:
766 return (f"<SwitchNode handle=0x{as_intptr(self._h_node):x}" 2ej
767 f" condition=0x{<unsigned long long>self._condition._c_handle:x}>") 2ej