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

1# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 

2# 

3# SPDX-License-Identifier: Apache-2.0 

4  

5"""GraphNode subclasses — EmptyNode through SwitchNode.""" 

6  

7from __future__ import annotations 

8  

9from libc.stddef cimport size_t 

10from libc.stdint cimport uintptr_t 

11from libc.string cimport memset as c_memset 

12  

13from cuda.bindings cimport cydriver 

14  

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 

64  

65from cuda.core._host_callback cimport ( 

66 _is_py_host_trampoline, 

67 _resolve_host_callback, 

68) 

69  

70from cuda.core.typing import GraphConditionalType 

71  

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] 

97  

98  

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 ) 

106  

107  

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

125  

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

140  

141  

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

149  

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

156  

157 cdef PreparedExecAttachment prepared 

158 HANDLE_RETURN(graph_prepare_exec_attachment( 1UzVuK4RSTBCDGHIEFYOAabJZ0

159 h_exec, owner0, owner1, &prepared)) 

160  

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

168  

169  

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

174  

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

186  

187  

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

193  

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)) 

203  

204  

205cdef bint _check_node_get_params(): 

206 """Whether cuGraphNodeGetParams, a 13.2 driver API, is available. 

207  

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 

213  

214  

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

222  

223  

224cdef void _reject_unsupported_kernel_node( 

225 cydriver.CUgraphNode node) except *: 

226 cdef cydriver.CUkernelNodeAttrValue cluster 

227 cdef cydriver.CUkernelNodeAttrValue cooperative 

228  

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") 

244  

245  

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

254  

255  

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)) 

266  

267  

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 ) 

290  

291  

292cdef class EmptyNode(GraphNode): 

293 """An empty (synchronization) node.""" 

294  

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

300  

301 def __repr__(self) -> str: 

302 return f"<EmptyNode handle=0x{as_intptr(self._h_node):x}>" 23f4fxg

303  

304  

305cdef class KernelNode(GraphNode): 

306 """A kernel launch node. 

307  

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 """ 

321  

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

334  

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, &params)) 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) 

349  

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

353  

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. 

362  

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. 

366  

367 .. warning:: 

368  

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 

385  

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=

402  

403 c_memset(&params, 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*>&params.kernel)) 

408 HANDLE_RETURN(graph_get_attachment( 1qpo

409 h_graph, node, &kernel_owner, &args_owner)) 

410  

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

432  

433 _set_definition_node_params( 1qpo

434 self._h_node, &params, 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

447  

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

452  

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

457  

458 @property 

459 def shmem_size(self) -> int: 

460 """Dynamic shared memory size in bytes.""" 

461 return self._shmem_size 2`ebb

462  

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?

467  

468 @property 

469 def config(self) -> LaunchConfig: 

470 """A LaunchConfig reconstructed from this node's grid, block, and shmem_size. 

471  

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?

477  

478  

479cdef class AllocNode(GraphNode): 

480 """A memory allocation node. 

481  

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 """ 

495  

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

509  

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, &params)) 2jbkbNbObPbbbabcbdbebfb5b6b7b8b9b!b#brb$b'b)b+b-b.b/b:b;b=b?b@b]b_b{bgbhb

517  

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" 

532  

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

537  

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

541  

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

545  

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

550  

551 @property 

552 def bytesize(self) -> int: 

553 """The number of bytes allocated.""" 

554 return self._bytesize 2UfVfjbkb

555  

556 @property 

557 def device_id(self) -> int: 

558 """The device on which the allocation was made.""" 

559 return self._device_id 2UfVfjbkb

560  

561 @property 

562 def memory_type(self) -> str: 

563 """The type of memory: ``"device"``, ``"host"``, or ``"managed"``.""" 

564 return self._memory_type 2UfVfjbkbgb

565  

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

570  

571  

572cdef class FreeNode(GraphNode): 

573 """A memory deallocation node. 

574  

575 Properties 

576 ---------- 

577 dptr : int 

578 The device pointer being freed. 

579 """ 

580  

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

589  

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

598  

599 def __repr__(self) -> str: 

600 return f"<FreeNode handle=0x{as_intptr(self._h_node):x} dptr=0x{self._dptr:x}>" 2yg

601  

602 @property 

603 def dptr(self) -> int: 

604 """The device pointer being freed.""" 

605 return self._dptr 2zgPbqb

606  

607  

608cdef class MemsetNode(GraphNode): 

609 """A memset node. 

610  

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 """ 

626  

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

642  

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, &params)) 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[

653  

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

657  

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. 

669  

670 Omitted parameters preserve their current values. ``dst_owner`` may 

671 only accompany a raw-address ``dst``. 

672  

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. 

677  

678 .. warning:: 

679  

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 

693  

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

699  

700 c_memset(&params, 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, &current)) 

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)) 

715  

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

722  

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'(

731  

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

740  

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

748  

749 _set_definition_node_params( 1mngc

750 self._h_node, &params, 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

758  

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

763  

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

768  

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

773  

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

778  

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

783  

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

788  

789  

790cdef class MemcpyNode(GraphNode): 

791 """A memcpy node. 

792  

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 """ 

802  

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

817  

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, &params)) 27 ibu a b d e f

825  

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

836  

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

840  

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

846  

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. 

857  

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. 

862  

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. 

867  

868 .. warning:: 

869  

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 

887  

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

894  

895 c_memset(&params, 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, &params.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

911  

912 if not _is_supported_memcpy_descriptor(&params.memcpy.copyParams): 1hlivwxrstjkabdef2c

913 raise NotImplementedError( 12

914 "updating multidimensional, pitched, offset, or array-backed " 

915 "memcpy nodes is not supported") 

916  

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

931  

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

967  

968 _set_definition_node_params( 1hlijkabdefc

969 self._h_node, &params, 

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

977  

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

982  

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

987  

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

992  

993  

994cdef class ChildGraphNode(GraphNode): 

995 """A child graph node. 

996  

997 Properties 

998 ---------- 

999 child_graph : GraphDefinition 

1000 The embedded graph definition (non-owning wrapper). 

1001 """ 

1002  

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

1011  

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

1023  

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

1027  

1028 def update(self, GraphDefinition child not None: GraphDefinition) -> None: 

1029 """Replace the embedded graph with a clone of ``child``. 

1030  

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 

1041  

1042 _require_graph_node_update_support() 1LN1:

1043 c_memset(&params, 0, sizeof(params)) 1LN1:

1044 params.type = cydriver.CU_GRAPH_NODE_TYPE_GRAPH 1LN1:

1045 params.graph.graph = as_cu(child._h_graph) 1LN1:

1046  

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, &params)) 

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

1060  

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 :

1065  

1066  

1067cdef class EventRecordNode(GraphNode): 

1068 """An event record node. 

1069  

1070 Properties 

1071 ---------- 

1072 event : Event 

1073 The event being recorded. 

1074 """ 

1075  

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

1084  

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

1094  

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

1098  

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 

1105  

1106 c_memset(&params, 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;

1109  

1110 _set_definition_node_params( 1;

1111 self._h_node, &params, event_owner) 

1112 self._h_event = event._h_event 1;

1113  

1114 @property 

1115 def event(self) -> Event: 

1116 """The event being recorded.""" 

1117 return Event._from_handle(self._h_event) 2BgNbXf0cYfIc; 4 @e

1118  

1119  

1120cdef class EventWaitNode(GraphNode): 

1121 """An event wait node. 

1122  

1123 Properties 

1124 ---------- 

1125 event : Event 

1126 The event being waited on. 

1127 """ 

1128  

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

1137  

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

1147  

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

1151  

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 

1158  

1159 c_memset(&params, 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)

1162  

1163 _set_definition_node_params( 1)

1164 self._h_node, &params, event_owner) 

1165 self._h_event = event._h_event 1)

1166  

1167 @property 

1168 def event(self) -> Event: 

1169 """The event being waited on.""" 

1170 return Event._from_handle(self._h_event) 2CgOb1c0fJc) R Ud

1171  

1172  

1173cdef class HostCallbackNode(GraphNode): 

1174 """A host callback node. 

1175  

1176 Properties 

1177 ---------- 

1178 callback : callable or None 

1179 The Python callable (None for ctypes function pointer callbacks). 

1180 """ 

1181  

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

1193  

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, &params)) 2Qb_ L ` { Rb| N 1 K :

1201  

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 :

1205  

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 :

1208  

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

1216  

1217 def update(self, fn, *, user_data=None) -> None: 

1218 """Replace the callback and user-data binding for this node. 

1219  

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``. 

1226  

1227 .. warning:: 

1228  

1229 Callbacks must not call CUDA API functions. Doing so may 

1230 deadlock or corrupt driver state. 

1231  

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 

1242  

1243 _resolve_host_callback( 2Ye* + Ze'd(d

1244 fn, user_data, &c_fn, &c_user_data, &fn_owner, &data_owner) 

1245 c_memset(&params, 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*+

1249  

1250 _set_definition_node_params( 1*+

1251 self._h_node, &params, 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*+

1255  

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

1260  

1261  

1262cdef class ConditionalNode(GraphNode): 

1263 """Base class for conditional nodes. 

1264  

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. 

1270  

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 """ 

1280  

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") 

1295  

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, &params) 1859!#6$%@

1303 cdef int cond_type_int = <int>params.conditional.type 1859!#6$%@

1304 cdef unsigned int size = params.conditional.size 1859!#6$%@

1305  

1306 cdef GraphCondition condition = GraphCondition.__new__(GraphCondition) 1859!#6$%@

1307 condition._c_handle = params.conditional.handle 1859!#6$%@

1308  

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$%@

1319  

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$

1330  

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$%@

1337  

1338 def __repr__(self) -> str: 

1339 return f"<ConditionalNode handle=0x{as_intptr(self._h_node):x}>" 

1340  

1341 @property 

1342 def condition(self) -> GraphCondition | None: 

1343 """The condition variable controlling execution.""" 

1344 return self._condition 2^eQf1fRf_eSf2fTf

1345  

1346 @property 

1347 def cond_type(self) -> GraphConditionalType | None: 

1348 """The conditional type: GraphConditionalType.IF, .WHILE, or .SWITCH 

1349  

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

1361  

1362 @property 

1363 def branches(self) -> tuple[GraphDefinition, ...]: 

1364 """The body graphs for each branch as a tuple of GraphDefinition. 

1365  

1366 Returns an empty tuple when reconstructed from the driver 

1367 pre-CUDA 13.2. 

1368 """ 

1369 return self._branches 2^eQf1fRf_eSf2fTfFgzc9 $ @

1370  

1371  

1372cdef class IfNode(ConditionalNode): 

1373 """An if-conditional node.""" 

1374  

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

1378  

1379 @property 

1380 def then(self) -> GraphDefinition: 

1381 """The 'then' branch graph.""" 

1382 return self._branches[0] 2QfSfGgyc8 #

1383  

1384  

1385cdef class IfElseNode(ConditionalNode): 

1386 """An if-else conditional node.""" 

1387  

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

1391  

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

1396  

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

1401  

1402  

1403cdef class WhileNode(ConditionalNode): 

1404 """A while-loop conditional node.""" 

1405  

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

1409  

1410 @property 

1411 def body(self) -> GraphDefinition: 

1412 """The loop body graph.""" 

1413 return self._branches[0] 2RfTfHgAc! %

1414  

1415  

1416cdef class SwitchNode(ConditionalNode): 

1417 """A switch conditional node.""" 

1418  

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

1422  

1423  

1424cdef class ExecutableGraphNode: 

1425 """A lightweight view pairing an executable graph with a source node. 

1426  

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 """ 

1431  

1432 def __init__(self): 

1433 raise RuntimeError( 2Ig

1434 "directly constructing an executable graph node is not supported") 

1435  

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 ) 

1441  

1442  

1443cdef class ExecutableKernelNode(ExecutableGraphNode): 

1444 """An executable kernel-node view.""" 

1445  

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. 

1454  

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 

1466  

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

1472  

1473 c_memset(&params, 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

1487  

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, &params, 

1493 kernel_owner, args_owner) 

1494  

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

1500  

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) 

1505  

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) 

1510  

1511  

1512cdef class ExecutableMemsetNode(ExecutableGraphNode): 

1513 """An executable memset-node view.""" 

1514  

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

1531  

1532 cdef cydriver.CUcontext ctx = NULL 1EF

1533 cdef cydriver.CUgraphNodeParams params 

1534 with nogil: 1EF

1535 HANDLE_RETURN(cydriver.cuCtxGetCurrent(&ctx)) 1EF

1536  

1537 c_memset(&params, 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, &params, dst_owner) 

1548  

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

1554  

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) 

1559  

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) 

1564  

1565  

1566cdef class ExecutableMemcpyNode(ExecutableGraphNode): 

1567 """An executable memcpy-node view.""" 

1568  

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. 

1577  

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

1592  

1593 c_memset(&params, 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, &params.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, &params, 

1622 dst_owner, src_owner) 

1623  

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

1629  

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) 

1634  

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) 

1639  

1640  

1641cdef class ExecutableChildGraphNode(ExecutableGraphNode): 

1642 """An executable child-graph-node view.""" 

1643  

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(&params, 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, &params) 

1653  

1654  

1655cdef class ExecutableEventRecordNode(ExecutableGraphNode): 

1656 """An executable event-record-node view.""" 

1657  

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(&params, 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, &params, event_owner) 

1668  

1669  

1670cdef class ExecutableEventWaitNode(ExecutableGraphNode): 

1671 """An executable event-wait-node view.""" 

1672  

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(&params, 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, &params, event_owner) 

1683  

1684  

1685cdef class ExecutableHostCallbackNode(ExecutableGraphNode): 

1686 """An executable host-callback-node view.""" 

1687  

1688 def update(self, fn, *, user_data=None) -> None: 

1689 """Replace the callback and user-data binding for future launches. 

1690  

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``. 

1696  

1697 .. warning:: 

1698  

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 

1707  

1708 _resolve_host_callback( 1VSTYOZ0

1709 fn, user_data, &c_fn, &c_user_data, &fn_owner, &data_owner) 

1710 c_memset(&params, 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, &params, 

1716 fn_owner, data_owner) 

1717  

1718  

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

1740  

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") 

1745  

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