Coverage for cuda/core/graph/_subclasses.pyx: 86.20%

732 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-16 01:23 +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.graph._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() 1LOUy39X+,qpohlimnY~}Nu5Z0KQMVWBCDGHIEF1;=?Rz_jkabdefgJ2Pc

101 if version < (12, 2, 0): 1LOUy39X+,qpohlimnY~}Nu5Z0KQMVWBCDGHIEF1;=?Rz_jkabdefgJ2Pc

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) 19X+,qpohlimnjkabdefgc

115 cdef cydriver.CUgraphNode node = as_cu(h_node) 19X+,qpohlimnjkabdefgc

116 if as_cu(h_graph) == NULL: 19X+,qpohlimnjkabdefgc

117 raise RuntimeError("GraphDefinition is no longer valid") 

118 if node == NULL: 19X+,qpohlimnjkabdefgc

119 raise RuntimeError("GraphNode has been destroyed") 

120 _require_graph_node_update_support() 19X+,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 19X+,qpohlimnjkabdefgc

125  

126 HANDLE_RETURN(graph_prepare_attachment( 19X+,qpohlimnjkabdefgc

127 h_graph, owner0, owner1, &prepared)) 

128 if update_ctx != NULL: 19X+,qpohlimnjkabdefgc

129 h_update_ctx = create_context_handle_ref(update_ctx) 1hlimnjkabdefgc

130 with nogil: 19X+,qpohlimnjkabdefgc

131 status = graph_node_set_params(node, params, h_update_ctx, &restore_status) 19X+,qpohlimnjkabdefgc

132 HANDLE_RETURN(status) 19X+,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: 19X+,qpohlimnjkabdefgc

137 HANDLE_RETURN(graph_commit_attachment(prepared, node)) 19X+,qpohlimnjkabdefgc

138 finally: 

139 HANDLE_RETURN(restore_status) 19X+,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() 1UyYNuKQMVWBCDGHIEF1RzabJ2P

149  

150 cdef cydriver.CUgraphExec graph_exec = as_cu(h_exec) 1UyYNuKQMVWBCDGHIEF1RzabJ2P

151 cdef cydriver.CUgraphNode node = as_cu(h_node) 1UyYNuKQMVWBCDGHIEF1RzabJ2P

152 if graph_exec == NULL: 1UyYNuKQMVWBCDGHIEF1RzabJ2P

153 raise RuntimeError("Graph has been closed") 

154 if node == NULL: 1UyYNuKQMVWBCDGHIEF1RzabJ2P

155 raise RuntimeError("GraphNode has been destroyed") 1N

156  

157 cdef PreparedExecAttachment prepared 

158 HANDLE_RETURN(graph_prepare_exec_attachment( 1UyYuKQMVWBCDGHIEF1RzabJ2P

159 h_exec, owner0, owner1, &prepared)) 

160  

161 cdef cydriver.CUresult status 

162 with nogil: 1UyYuKQMVWBCDGHIEF1RzabJ2P

163 status = cydriver.cuGraphExecNodeSetParams( 1UyYuKQMVWBCDGHIEF1RzabJ2P

164 graph_exec, node, params) 

165 if status == cydriver.CUDA_SUCCESS: 1UyYuKQMVWBCDGHIEF1RzabJ2P

166 graph_commit_exec_attachment(prepared) 1UyYuKQMVWBCDGHIEF1Rza2P

167 HANDLE_RETURN(status) 1UyYuKQMVWBCDGHIEF1RzabJ2P

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}5Z0

174  

175 cdef cydriver.CUgraphExec graph_exec = as_cu(h_exec) 1}5Z0

176 cdef cydriver.CUgraphNode node = as_cu(h_node) 1}5Z0

177 cdef unsigned int enabled 

178 if graph_exec == NULL: 1}5Z0

179 raise RuntimeError("Graph has been closed") 

180 if node == NULL: 1}5Z0

181 raise RuntimeError("GraphNode has been destroyed") 1}

182 with nogil: 15Z0

183 HANDLE_RETURN(cydriver.cuGraphNodeGetEnabled( 15Z0

184 graph_exec, node, &enabled)) 

185 return enabled != 0 15Z0

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~5Z0

193  

194 cdef cydriver.CUgraphExec graph_exec = as_cu(h_exec) 1~5Z0

195 cdef cydriver.CUgraphNode node = as_cu(h_node) 1~5Z0

196 if graph_exec == NULL: 1~5Z0

197 raise RuntimeError("Graph has been closed") 

198 if node == NULL: 1~5Z0

199 raise RuntimeError("GraphNode has been destroyed") 1~

200 with nogil: 15Z0

201 HANDLE_RETURN(cydriver.cuGraphNodeSetEnabled( 15Z0

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) 1!6#$%7'(@hlimnvwx)*rstSTjkabdef4gc

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])) 1!6#$%7'(@hlimnvwx)*rstSTjkabdef4gc

220 with nogil: 1!6#$%7'(@hlimnvwx)*rstSTjkabdef4gc

221 HANDLE_RETURN(cydriver.cuGraphNodeGetParams(node, params)) 1!6#$%7'(@hlimnvwx)*rstSTjkabdef4gc

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 1hlivwxrstjk4c

252 or memory_type == cydriver.CU_MEMORYTYPE_DEVICE 1hlivwxrstjkabdef4c

253 or memory_type == cydriver.CU_MEMORYTYPE_UNIFIED) 1hlivwxrstjkabdef4c

254  

255  

256cdef str _memcpy_memory_type_tag(cydriver.CUmemorytype memory_type): 

257 if memory_type == cydriver.CU_MEMORYTYPE_HOST: 2f 1e

258 return "H" 

259 if memory_type == cydriver.CU_MEMORYTYPE_DEVICE: 2f 1e

260 return "D" 21e

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

272 and _is_linear_memcpy_memory_type(params.dstMemoryType) 1hlivwxrstjkabdef4c

273 and params.srcXInBytes == 0 1hlivwxrstjkabdef4c

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~cabtbadbdcdddedubfdqbvbgd^fwbhdxbidjdkdld_fmdnd`fod{f|f8 WdXdYdZd0d}fZf~fagbg1dcgdgegLbR 8d9dpdyb0fqdzbrdAbA sdBbtdCbudDbvdEbwdFbxdGbydHbzdIb

298 n._h_node = h_node 2;f=f^c_c?f- . / : `c{c|c@f[f]f}csb~cabtbadbdcdddedubfdqbvbgd^fwbhdxbidjdkdld_fmdnd`fod{f|f8 WdXdYdZd0d}fZf~fagbg1dcgdgegLbR 8d9dpdyb0fqdzbrdAbA sdBbtdCbudDbvdEbwdFbxdGbydHbzdIb

299 return n 2;f=f^c_c?f- . / : `c{c|c@f[f]f}csb~cabtbadbdcdddedubfdqbvbgd^fwbhdxbidjdkdld_fmdnd`fod{f|f8 WdXdYdZd0d}fZf~fagbg1dcgdgegLbR 8d9dpdyb0fqdzbrdAbA sdBbtdCbudDbvdEbwdFbxdGbydHbzdIb

300  

301 def __repr__(self) -> str: 

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

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) 2Dc2eEcFcGcAd3e4e5e6e7e8e9etcBducCdvcDdwcEdxcFdycGdzc!eAcqcBcCcMb#e$e+d(c%e'e` WdXdYdZd0d[ y q p o McNcOc,d-d.d~ } N JbKb5 TbB C D Lb= rc? z _ scJ (eHd)eId*eJd+eA Kd,eLd-eMd.eNd/eOd:ePd;eQd=eRd?e

328 n._h_node = h_node 2Dc2eEcFcGcAd3e4e5e6e7e8e9etcBducCdvcDdwcEdxcFdycGdzc!eAcqcBcCcMb#e$e+d(c%e'e` WdXdYdZd0d[ y q p o McNcOc,d-d.d~ } N JbKb5 TbB C D Lb= rc? z _ scJ (eHd)eId*eJd+eA Kd,eLd-eMd.eNd/eOd:ePd;eQd=eRd?e

329 n._grid = grid 2Dc2eEcFcGcAd3e4e5e6e7e8e9etcBducCdvcDdwcEdxcFdycGdzc!eAcqcBcCcMb#e$e+d(c%e'e` WdXdYdZd0d[ y q p o McNcOc,d-d.d~ } N JbKb5 TbB C D Lb= rc? z _ scJ (eHd)eId*eJd+eA Kd,eLd-eMd.eNd/eOd:ePd;eQd=eRd?e

330 n._block = block 2Dc2eEcFcGcAd3e4e5e6e7e8e9etcBducCdvcDdwcEdxcFdycGdzc!eAcqcBcCcMb#e$e+d(c%e'e` WdXdYdZd0d[ y q p o McNcOc,d-d.d~ } N JbKb5 TbB C D Lb= rc? z _ scJ (eHd)eId*eJd+eA Kd,eLd-eMd.eNd/eOd:ePd;eQd=eRd?e

331 n._shmem_size = shmem_size 2Dc2eEcFcGcAd3e4e5e6e7e8e9etcBducCdvcDdwcEdxcFdycGdzc!eAcqcBcCcMb#e$e+d(c%e'e` WdXdYdZd0d[ y q p o McNcOc,d-d.d~ } N JbKb5 TbB C D Lb= rc? z _ scJ (eHd)eId*eJd+eA Kd,eLd-eMd.eNd/eOd:ePd;eQd=eRd?e

332 n._h_kernel = h_kernel 2Dc2eEcFcGcAd3e4e5e6e7e8e9etcBducCdvcDdwcEdxcFdycGdzc!eAcqcBcCcMb#e$e+d(c%e'e` WdXdYdZd0d[ y q p o McNcOc,d-d.d~ } N JbKb5 TbB C D Lb= rc? z _ scJ (eHd)eId*eJd+eA Kd,eLd-eMd.eNd/eOd:ePd;eQd=eRd?e

333 return n 2Dc2eEcFcGcAd3e4e5e6e7e8e9etcBducCdvcDdwcEdxcFdycGdzc!eAcqcBcCcMb#e$e+d(c%e'e` WdXdYdZd0d[ y q p o McNcOc,d-d.d~ } N JbKb5 TbB C D Lb= rc? z _ scJ (eHd)eId*eJd+eA Kd,eLd-eMd.eNd/eOd:ePd;eQd=eRd?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) 2DcEcFcGctcAcqcBcCcMb` [

339 cdef cydriver.CUDA_KERNEL_NODE_PARAMS params 

340 with nogil: 2DcEcFcGctcAcqcBcCcMb` [

341 HANDLE_RETURN(cydriver.cuGraphKernelNodeGetParams(node, &params)) 2DcEcFcGctcAcqcBcCcMb` [

342 cdef KernelHandle h_kernel = create_kernel_handle_ref(params.kern) 2DcEcFcGctcAcqcBcCcMb` [

343 return KernelNode._create_with_params( 2DcEcFcGctcAcqcBcCcMb` [

344 h_node, 

345 (params.gridDimX, params.gridDimY, params.gridDimZ), 2DcEcFcGctcAcqcBcCcMb` [

346 (params.blockDimX, params.blockDimY, params.blockDimZ), 2DcEcFcGctcAcqcBcCcMb` [

347 params.sharedMemBytes, 

348 h_kernel) 

349  

350 def __repr__(self) -> str: 

351 return (f"<KernelNode handle=0x{as_intptr(self._h_node):x}" 2y z gg

352 f" kernel=0x{as_intptr(self._h_kernel):x}>") 2y z gg

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 McNcOc,d-d.d= rc? _ sc

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 McNcOc= rc? _ sc

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 McNcOc= rc? _ sc

383 cdef cydriver.CUgraphNode node = as_cu(self._h_node) 2q p o McNcOc= rc? _ sc

384 cdef cydriver.CUgraphNodeParams params 

385  

386 if config is not None: 2q p o McNcOc= rc? _ sc

387 c_config = config 2p McNcOcrc_ sc

388 if (c_config.cluster is not None or 2p _ sc

389 c_config.is_cooperative): 2p _ sc

390 raise NotImplementedError( 2sc

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 = rc?

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 = rc?

476 shmem_size=self._shmem_size) 2_ebbq p o B C D = rc?

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) 2!d#dPc/d:d;d=d^c?d_c@d[dQcRcScTcUc- . / : lbmbnbob]d^d_d`c{c|c`d{d}c)c*cVcucsbUbVbWbXbjb|dkb}d~cNb+cOb,cPbWcbbvcabtbcbYbdbZbeb0bfb1b~dadaebdbecedecdeeddfegeheieed-c.cXcwcub2b3b4b5b6bje7bke8bfd9b/c!b:c#bYc$bxcqbvb%b'b(b)b*b+b,b-b.ble/bme:bgd;b;c=b=c?bZc@bycwb[b]b^b_b`b{b|b}bneoehd?c@c0czcxb~bacbcccpeidqejdresetekdueldvewexemdyendzeAeod$dBe1c2cgbhbpb8 HcCepd3cybdcDeqd4czbecEerd5cAbfcA Fesd6cBbgcGetd7cCbhcHeud8cDbicIevd9cEbjcJewd!cFbkcKexd#cGblcLeyd$cHbmcMezd%cIbnc

502 n._h_node = h_node 2!d#dPc/d:d;d=d^c?d_c@d[dQcRcScTcUc- . / : lbmbnbob]d^d_d`c{c|c`d{d}c)c*cVcucsbUbVbWbXbjb|dkb}d~cNb+cOb,cPbWcbbvcabtbcbYbdbZbeb0bfb1b~dadaebdbecedecdeeddfegeheieed-c.cXcwcub2b3b4b5b6bje7bke8bfd9b/c!b:c#bYc$bxcqbvb%b'b(b)b*b+b,b-b.ble/bme:bgd;b;c=b=c?bZc@bycwb[b]b^b_b`b{b|b}bneoehd?c@c0czcxb~bacbcccpeidqejdresetekdueldvewexemdyendzeAeod$dBe1c2cgbhbpb8 HcCepd3cybdcDeqd4czbecEerd5cAbfcA Fesd6cBbgcGetd7cCbhcHeud8cDbicIevd9cEbjcJewd!cFbkcKexd#cGblcLeyd$cHbmcMezd%cIbnc

503 n._dptr = dptr 2!d#dPc/d:d;d=d^c?d_c@d[dQcRcScTcUc- . / : lbmbnbob]d^d_d`c{c|c`d{d}c)c*cVcucsbUbVbWbXbjb|dkb}d~cNb+cOb,cPbWcbbvcabtbcbYbdbZbeb0bfb1b~dadaebdbecedecdeeddfegeheieed-c.cXcwcub2b3b4b5b6bje7bke8bfd9b/c!b:c#bYc$bxcqbvb%b'b(b)b*b+b,b-b.ble/bme:bgd;b;c=b=c?bZc@bycwb[b]b^b_b`b{b|b}bneoehd?c@c0czcxb~bacbcccpeidqejdresetekdueldvewexemdyendzeAeod$dBe1c2cgbhbpb8 HcCepd3cybdcDeqd4czbecEerd5cAbfcA Fesd6cBbgcGetd7cCbhcHeud8cDbicIevd9cEbjcJewd!cFbkcKexd#cGblcLeyd$cHbmcMezd%cIbnc

504 n._bytesize = bytesize 2!d#dPc/d:d;d=d^c?d_c@d[dQcRcScTcUc- . / : lbmbnbob]d^d_d`c{c|c`d{d}c)c*cVcucsbUbVbWbXbjb|dkb}d~cNb+cOb,cPbWcbbvcabtbcbYbdbZbeb0bfb1b~dadaebdbecedecdeeddfegeheieed-c.cXcwcub2b3b4b5b6bje7bke8bfd9b/c!b:c#bYc$bxcqbvb%b'b(b)b*b+b,b-b.ble/bme:bgd;b;c=b=c?bZc@bycwb[b]b^b_b`b{b|b}bneoehd?c@c0czcxb~bacbcccpeidqejdresetekdueldvewexemdyendzeAeod$dBe1c2cgbhbpb8 HcCepd3cybdcDeqd4czbecEerd5cAbfcA Fesd6cBbgcGetd7cCbhcHeud8cDbicIevd9cEbjcJewd!cFbkcKexd#cGblcLeyd$cHbmcMezd%cIbnc

505 n._device_id = device_id 2!d#dPc/d:d;d=d^c?d_c@d[dQcRcScTcUc- . / : lbmbnbob]d^d_d`c{c|c`d{d}c)c*cVcucsbUbVbWbXbjb|dkb}d~cNb+cOb,cPbWcbbvcabtbcbYbdbZbeb0bfb1b~dadaebdbecedecdeeddfegeheieed-c.cXcwcub2b3b4b5b6bje7bke8bfd9b/c!b:c#bYc$bxcqbvb%b'b(b)b*b+b,b-b.ble/bme:bgd;b;c=b=c?bZc@bycwb[b]b^b_b`b{b|b}bneoehd?c@c0czcxb~bacbcccpeidqejdresetekdueldvewexemdyendzeAeod$dBe1c2cgbhbpb8 HcCepd3cybdcDeqd4czbecEerd5cAbfcA Fesd6cBbgcGetd7cCbhcHeud8cDbicIevd9cEbjcJewd!cFbkcKexd#cGblcLeyd$cHbmcMezd%cIbnc

506 n._memory_type = memory_type 2!d#dPc/d:d;d=d^c?d_c@d[dQcRcScTcUc- . / : lbmbnbob]d^d_d`c{c|c`d{d}c)c*cVcucsbUbVbWbXbjb|dkb}d~cNb+cOb,cPbWcbbvcabtbcbYbdbZbeb0bfb1b~dadaebdbecedecdeeddfegeheieed-c.cXcwcub2b3b4b5b6bje7bke8bfd9b/c!b:c#bYc$bxcqbvb%b'b(b)b*b+b,b-b.ble/bme:bgd;b;c=b=c?bZc@bycwb[b]b^b_b`b{b|b}bneoehd?c@c0czcxb~bacbcccpeidqejdresetekdueldvewexemdyendzeAeod$dBe1c2cgbhbpb8 HcCepd3cybdcDeqd4czbecEerd5cAbfcA Fesd6cBbgcGetd7cCbhcHeud8cDbicIevd9cEbjcJewd!cFbkcKexd#cGblcLeyd$cHbmcMezd%cIbnc

507 n._peer_access = peer_access 2!d#dPc/d:d;d=d^c?d_c@d[dQcRcScTcUc- . / : lbmbnbob]d^d_d`c{c|c`d{d}c)c*cVcucsbUbVbWbXbjb|dkb}d~cNb+cOb,cPbWcbbvcabtbcbYbdbZbeb0bfb1b~dadaebdbecedecdeeddfegeheieed-c.cXcwcub2b3b4b5b6bje7bke8bfd9b/c!b:c#bYc$bxcqbvb%b'b(b)b*b+b,b-b.ble/bme:bgd;b;c=b=c?bZc@bycwb[b]b^b_b`b{b|b}bneoehd?c@c0czcxb~bacbcccpeidqejdresetekdueldvewexemdyendzeAeod$dBe1c2cgbhbpb8 HcCepd3cybdcDeqd4czbecEerd5cAbfcA Fesd6cBbgcGetd7cCbhcHeud8cDbicIevd9cEbjcJewd!cFbkcKexd#cGblcLeyd$cHbmcMezd%cIbnc

508 return n 2!d#dPc/d:d;d=d^c?d_c@d[dQcRcScTcUc- . / : lbmbnbob]d^d_d`c{c|c`d{d}c)c*cVcucsbUbVbWbXbjb|dkb}d~cNb+cOb,cPbWcbbvcabtbcbYbdbZbeb0bfb1b~dadaebdbecedecdeeddfegeheieed-c.cXcwcub2b3b4b5b6bje7bke8bfd9b/c!b:c#bYc$bxcqbvb%b'b(b)b*b+b,b-b.ble/bme:bgd;b;c=b=c?bZc@bycwb[b]b^b_b`b{b|b}bneoehd?c@c0czcxb~bacbcccpeidqejdresetekdueldvewexemdyendzeAeod$dBe1c2cgbhbpb8 HcCepd3cybdcDeqd4czbecEerd5cAbfcA Fesd6cBbgcGetd7cCbhcHeud8cDbicIevd9cEbjcJewd!cFbkcKexd#cGblcLeyd$cHbmcMezd%cIbnc

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) 2jbkbNbObPbbbabcbdbebfb6b7b8b9b!b#b$bqb%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: 2jbkbNbObPbbbabcbdbebfb6b7b8b9b!b#b$bqb%b(b*b,b.b/b:b;b=b?b@b[b^b`b|bgbhb

516 HANDLE_RETURN(cydriver.cuGraphMemAllocNodeGetParams(node, &params)) 2jbkbNbObPbbbabcbdbebfb6b7b8b9b!b#b$bqb%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: 2jbkbNbObPbbbabcbdbebfb6b7b8b9b!b#b$bqb%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: 2jbkbNbObPbbbabcbdbebfb6b7b8b9b!b#b$bqb%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" 2jbkbNbObPbbbabcbdbebfb6b7b8b9b!b#b$bqb%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 = [] 2jbkbNbObPbbbabcbdbebfb6b7b8b9b!b#b$bqb%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): 2jbkbNbObPbbbabcbdbebfb6b7b8b9b!b#b$bqb%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( 2jbkbNbObPbbbabcbdbebfb6b7b8b9b!b#b$bqb%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)) 2jbkbNbObPbbbabcbdbebfb6b7b8b9b!b#b$bqb%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}" 2hg

544 f" dptr=0x{self._dptr:x} size={self._bytesize}>") 2hg

545  

546 @property 

547 def dptr(self) -> int: 

548 """The device pointer for the allocation.""" 

549 return self._dptr 2!d#dPcQcRcScTcUc- . / : lbmbnbobRfSfVcsbUbVbWbXbjbkbWctbYbZb0b1bXcub2b3b4b5bYcvb'b)b+b-bZcwb]b_b{b}b0cxb~bacbccc$dgbpb8 3cybdc4czbec5cAbfcA 6cBbgc7cCbhc8cDbic9cEbjc!cFbkc#cGblc$cHbmc%cIbnc

550  

551 @property 

552 def bytesize(self) -> int: 

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

554 return self._bytesize 2RfSfjbkb

555  

556 @property 

557 def device_id(self) -> int: 

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

559 return self._device_id 2RfSfjbkb

560  

561 @property 

562 def memory_type(self) -> str: 

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

564 return self._memory_type 2RfSfjbkbgb

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 2RfSfjbkbhb

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) 2PcQcRcScTcUc- . / : lbmbnbobVcWcXcYcZc0cpb3c4c5cA 6c7c8c9c!c#c$c%c

586 n._h_node = h_node 2PcQcRcScTcUc- . / : lbmbnbobVcWcXcYcZc0cpb3c4c5cA 6c7c8c9c!c#c$c%c

587 n._dptr = dptr 2PcQcRcScTcUc- . / : lbmbnbobVcWcXcYcZc0cpb3c4c5cA 6c7c8c9c!c#c$c%c

588 return n 2PcQcRcScTcUc- . / : lbmbnbobVcWcXcYcZc0cpb3c4c5cA 6c7c8c9c!c#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) 2pb

594 cdef cydriver.CUdeviceptr dptr 

595 with nogil: 2pb

596 HANDLE_RETURN(cydriver.cuGraphMemFreeNodeGetParams(node, &dptr)) 2pb

597 return FreeNode._create_with_params(h_node, dptr) 2pb

598  

599 def __repr__(self) -> str: 

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

601  

602 @property 

603 def dptr(self) -> int: 

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

605 return self._dptr 2tgPbpb

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- . / : lbmbnbobUbVbWbXbYbZb0b1b2b3b4b5b'b)b+b-b]b_b{b}b~bacbccc%d'd(d[ [cm n ) * 2d3d0 E F S T g occ dcecfcA gchcicjckclcmcnc

634 n._h_node = h_node 2- . / : lbmbnbobUbVbWbXbYbZb0b1b2b3b4b5b'b)b+b-b]b_b{b}b~bacbccc%d'd(d[ [cm n ) * 2d3d0 E F S T g occ dcecfcA gchcicjckclcmcnc

635 n._dptr = dptr 2- . / : lbmbnbobUbVbWbXbYbZb0b1b2b3b4b5b'b)b+b-b]b_b{b}b~bacbccc%d'd(d[ [cm n ) * 2d3d0 E F S T g occ dcecfcA gchcicjckclcmcnc

636 n._value = value 2- . / : lbmbnbobUbVbWbXbYbZb0b1b2b3b4b5b'b)b+b-b]b_b{b}b~bacbccc%d'd(d[ [cm n ) * 2d3d0 E F S T g occ dcecfcA gchcicjckclcmcnc

637 n._element_size = element_size 2- . / : lbmbnbobUbVbWbXbYbZb0b1b2b3b4b5b'b)b+b-b]b_b{b}b~bacbccc%d'd(d[ [cm n ) * 2d3d0 E F S T g occ dcecfcA gchcicjckclcmcnc

638 n._width = width 2- . / : lbmbnbobUbVbWbXbYbZb0b1b2b3b4b5b'b)b+b-b]b_b{b}b~bacbccc%d'd(d[ [cm n ) * 2d3d0 E F S T g occ dcecfcA gchcicjckclcmcnc

639 n._height = height 2- . / : lbmbnbobUbVbWbXbYbZb0b1b2b3b4b5b'b)b+b-b]b_b{b}b~bacbccc%d'd(d[ [cm n ) * 2d3d0 E F S T g occ dcecfcA gchcicjckclcmcnc

640 n._pitch = pitch 2- . / : lbmbnbobUbVbWbXbYbZb0b1b2b3b4b5b'b)b+b-b]b_b{b}b~bacbccc%d'd(d[ [cm n ) * 2d3d0 E F S T g occ dcecfcA gchcicjckclcmcnc

641 return n 2- . / : lbmbnbobUbVbWbXbYbZb0b1b2b3b4b5b'b)b+b-b]b_b{b}b~bacbccc%d'd(d[ [cm n ) * 2d3d0 E F S T g occ dcecfcA gchcicjckclcmcnc

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}" 2ig

656 f" dptr=0x{self._dptr:x} value={self._value}>") 2ig

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 ) * 2d3dS T g c

687 cdef GraphHandle h_graph 

688 cdef cydriver.CUgraphNode node = as_cu(self._h_node) 1mn)*STgc

689 cdef cydriver.CUcontext ctx = NULL 1mn)*STgc

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

695 raise ValueError("dst_owner requires dst") 1g

696 if (dst is None and value is None and width is None and 1mn)*STgc

697 height is None and pitch is None): 1g

698 return 1g

699  

700 c_memset(&params, 0, sizeof(params)) 1mn)*STgc

701 params.type = cydriver.CU_GRAPH_NODE_TYPE_MEMSET 1mn)*STgc

702 with nogil: 1mn)*STgc

703 HANDLE_RETURN(cydriver.cuGraphMemsetNodeGetParams( 1mn)*STgc

704 node, &current)) 

705 IF CUDA_CORE_BUILD_MAJOR >= 13: 

706 if _check_node_get_params(): 1mn)*STgc

707 _node_get_params(node, &queried) 1mn)*STgc

708 ctx = queried.memset.ctx 1mn)*STgc

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

717 cdef unsigned int c_value = current.value 1mn)*STgc

718 cdef unsigned int c_element_size = current.elementSize 1mn)*STgc

719 cdef size_t c_width = current.width 1mn)*STgc

720 cdef size_t c_height = current.height 1mn)*STgc

721 cdef size_t c_pitch = current.pitch 1mn)*STgc

722  

723 if dst is None: 1mn)*STgc

724 h_graph = graph_node_get_graph(self._h_node) 1nSTgc

725 HANDLE_RETURN(graph_get_attachment( 1nSTgc

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: 1mnSTgc

733 c_value, c_element_size = _parse_fill_value(value) 1mnSTc

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 S T

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 S T 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 S T

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 S T 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 S T 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 S T 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- . / : sbtbubvbwbxbNeOe8 ibIcJcPeQeReSeTeUeVeh l i v w x SdTdUdu Z G H I r s t j k a b d e f 4 g occ ybzbAbA BbCbDbEbFbGbHbIb

810 n._h_node = h_node 2- . / : sbtbubvbwbxbNeOe8 ibIcJcPeQeReSeTeUeVeh l i v w x SdTdUdu Z G H I r s t j k a b d e f 4 g occ ybzbAbA BbCbDbEbFbGbHbIb

811 n._dst = dst 2- . / : sbtbubvbwbxbNeOe8 ibIcJcPeQeReSeTeUeVeh l i v w x SdTdUdu Z G H I r s t j k a b d e f 4 g occ ybzbAbA BbCbDbEbFbGbHbIb

812 n._src = src 2- . / : sbtbubvbwbxbNeOe8 ibIcJcPeQeReSeTeUeVeh l i v w x SdTdUdu Z G H I r s t j k a b d e f 4 g occ ybzbAbA BbCbDbEbFbGbHbIb

813 n._size = size 2- . / : sbtbubvbwbxbNeOe8 ibIcJcPeQeReSeTeUeVeh l i v w x SdTdUdu Z G H I r s t j k a b d e f 4 g occ ybzbAbA BbCbDbEbFbGbHbIb

814 n._dst_type = dst_type 2- . / : sbtbubvbwbxbNeOe8 ibIcJcPeQeReSeTeUeVeh l i v w x SdTdUdu Z G H I r s t j k a b d e f 4 g occ ybzbAbA BbCbDbEbFbGbHbIb

815 n._src_type = src_type 2- . / : sbtbubvbwbxbNeOe8 ibIcJcPeQeReSeTeUeVeh l i v w x SdTdUdu Z G H I r s t j k a b d e f 4 g occ ybzbAbA BbCbDbEbFbGbHbIb

816 return n 2- . / : sbtbubvbwbxbNeOe8 ibIcJcPeQeReSeTeUeVeh l i v w x SdTdUdu Z G H I r s t j k a b d e f 4 g occ ybzbAbA 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) 28 ibu a b d e f

822 cdef cydriver.CUDA_MEMCPY3D params 

823 with nogil: 28 ibu a b d e f

824 HANDLE_RETURN(cydriver.cuGraphMemcpyNodeGetParams(node, &params)) 28 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: 28 ibu a b d e f

829 dst = <cydriver.CUdeviceptr><uintptr_t>params.dstHost 2ib

830 else: 

831 dst = params.dstDevice 18uabdef

832 if params.srcMemoryType == cydriver.CU_MEMORYTYPE_HOST: 28 ibu a b d e f

833 src = <cydriver.CUdeviceptr><uintptr_t>params.srcHost 2ib

834 else: 

835 src = params.srcDevice 18uabdef

836  

837 return MemcpyNode._create_with_params( 28 ibu a b d e f

838 h_node, dst, src, params.WidthInBytes, 

839 params.dstMemoryType, params.srcMemoryType) 28 ibu a b d e f

840  

841 def __repr__(self) -> str: 

842 cdef str dt = _memcpy_memory_type_tag(self._dst_type) 2f 1e

843 cdef str st = _memcpy_memory_type_tag(self._src_type) 2f 1e

844 return (f"<MemcpyNode handle=0x{as_intptr(self._h_node):x}" 2f 1e

845 f" dst=0x{self._dst:x}({dt}) src=0x{self._src:x}({st}) size={self._size}>") 2f 1e

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 SdTdUdr s t j k a b d e f 4 g c

876 cdef cydriver.CUdeviceptr c_src = self._src 2h l i v w x SdTdUdr s t j k a b d e f 4 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 SdTdUdr s t j k a b d e f 4 g c

880 cdef GraphHandle h_graph = graph_node_get_graph(self._h_node) 1hlivwxrstjkabdef4gc

881 cdef cydriver.CUgraphNode node = as_cu(self._h_node) 1hlivwxrstjkabdef4gc

882 cdef cydriver.CUcontext ctx = NULL 1hlivwxrstjkabdef4gc

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: 1hlivwxrstjkabdef4gc

889 raise ValueError("dst_owner requires dst") 1g

890 if src is None and src_owner is not None: 1hlivwxrstjkabdef4gc

891 raise ValueError("src_owner requires src") 1g

892 if dst is None and src is None and size is None: 1hlivwxrstjkabdef4gc

893 return 1g

894  

895 c_memset(&params, 0, sizeof(params)) 1hlivwxrstjkabdef4c

896 params.type = cydriver.CU_GRAPH_NODE_TYPE_MEMCPY 1hlivwxrstjkabdef4c

897 with nogil: 1hlivwxrstjkabdef4c

898 HANDLE_RETURN(cydriver.cuGraphMemcpyNodeGetParams( 1hlivwxrstjkabdef4c

899 node, &params.memcpy.copyParams)) 

900 IF CUDA_CORE_BUILD_MAJOR >= 13: 

901 if _check_node_get_params(): 1hlivwxrstjkabdef4c

902 _node_get_params(node, &queried) 1hlivwxrstjkabdef4c

903 ctx = queried.memcpy.copyCtx 1hlivwxrstjkabdef4c

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 1hlivwxrstjkabdef4c

911  

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

913 raise NotImplementedError( 14

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 2fgab8 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 2fgab8 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 2fgab8 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) 2QbAdBdCdDdEdFdGd] MbL Tf{ 4d^ ` rb| O 1dU 3 Vd]cK ; HdIdJdA KdLdMdNdOdPdQdRd

1008 n._h_node = h_node 2QbAdBdCdDdEdFdGd] MbL Tf{ 4d^ ` rb| O 1dU 3 Vd]cK ; HdIdJdA KdLdMdNdOdPdQdRd

1009 n._h_child_graph = h_child_graph 2QbAdBdCdDdEdFdGd] MbL Tf{ 4d^ ` rb| O 1dU 3 Vd]cK ; HdIdJdA KdLdMdNdOdPdQdRd

1010 return n 2QbAdBdCdDdEdFdGd] MbL Tf{ 4d^ ` rb| O 1dU 3 Vd]cK ; HdIdJdA KdLdMdNdOdPdQdRd

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{^`|O

1016 cdef cydriver.CUgraph child_graph = NULL 1]L{^`|O

1017 with nogil: 1]L{^`|O

1018 HANDLE_RETURN(cydriver.cuGraphChildGraphNodeGetGraph(node, &child_graph)) 1]L{^`|O

1019 cdef GraphHandle h_graph = graph_node_get_graph(h_node) 1]L{^`|O

1020 cdef GraphHandle h_child = create_child_graph_handle( 1]L{^`|O

1021 child_graph, h_graph, node) 

1022 return ChildGraphNode._create_with_params(h_node, h_child) 1]L{^`|O

1023  

1024 def __repr__(self) -> str: 

1025 return (f"<ChildGraphNode handle=0x{as_intptr(self._h_node):x}" 2] L ^ rb1dU jg

1026 f" child=0x{as_intptr(self._h_child_graph):x}>") 2] L ^ rb1dU jg

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 O 3 ]c;

1034 GD_check_valid(child) 1LO3;

1035 cdef GraphHandle h_parent = graph_node_get_graph(self._h_node) 1LO3;

1036 cdef GraphHandle h_replacement 

1037 cdef cydriver.CUgraphNode node = as_cu(self._h_node) 1LO3;

1038 cdef cydriver.CUgraphNodeParams params 

1039 cdef cydriver.CUresult commit_status 

1040 cdef PreparedChildGraphUpdate prepared 

1041  

1042 _require_graph_node_update_support() 1LO3;

1043 c_memset(&params, 0, sizeof(params)) 1LO3;

1044 params.type = cydriver.CU_GRAPH_NODE_TYPE_GRAPH 1LO3;

1045 params.graph.graph = as_cu(child._h_graph) 1LO3;

1046  

1047 HANDLE_RETURN(graph_prepare_child_graph_update( 1LO3;

1048 h_parent, self._h_child_graph, node, 

1049 child._h_graph, &prepared)) 

1050 with nogil: 1LO3

1051 HANDLE_RETURN(cydriver.cuGraphNodeSetParams( 1LO3

1052 node, &params)) 

1053 try: 1LO3

1054 commit_status = graph_commit_child_graph_update( 1LO3

1055 prepared, &h_replacement) 

1056 finally: 

1057 if h_replacement: 1LO3

1058 self._h_child_graph = h_replacement 1LO3

1059 HANDLE_RETURN(commit_status) 1LO3

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) 2Qbtcug] MbL Tf{ ^ ` rb| O 1d3 Vd]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) 2We)c+c-c/c;c?cUf1cVfXeYegbhbKcLcpb8 ib(c9 X 5dRbQ M 'cpc1f2f3fA 4f5f6f7f8f9f!f#f

1081 n._h_node = h_node 2We)c+c-c/c;c?cUf1cVfXeYegbhbKcLcpb8 ib(c9 X 5dRbQ M 'cpc1f2f3fA 4f5f6f7f8f9f!f#f

1082 n._h_event = h_event 2We)c+c-c/c;c?cUf1cVfXeYegbhbKcLcpb8 ib(c9 X 5dRbQ M 'cpc1f2f3fA 4f5f6f7f8f9f!f#f

1083 return n 2We)c+c-c/c;c?cUf1cVfXeYegbhbKcLcpb8 ib(c9 X 5dRbQ M 'cpc1f2f3fA 4f5f6f7f8f9f!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) 2Kc

1089 cdef cydriver.CUevent event 

1090 with nogil: 2Kc

1091 HANDLE_RETURN(cydriver.cuGraphEventRecordNodeGetEvent(node, &event)) 2Kc

1092 cdef EventHandle h_event = create_event_handle_ref(event) 2Kc

1093 return EventRecordNode._create_with_params(h_node, h_event) 2Kc

1094  

1095 def __repr__(self) -> str: 

1096 return (f"<EventRecordNode handle=0x{as_intptr(self._h_node):x}" 2kg

1097 f" event=0x{as_intptr(self._h_event):x}>") 2kg

1098  

1099 def update(self, Event event not None: Event) -> None: 

1100 """Replace the event recorded by this node.""" 

1101 GN_check_valid(self) 29 Rb'c

1102 Event_check_open(event) 29 'c

1103 cdef OpaqueHandle event_owner = event._h_event 19

1104 cdef cydriver.CUgraphNodeParams params 

1105  

1106 c_memset(&params, 0, sizeof(params)) 19

1107 params.type = cydriver.CU_GRAPH_NODE_TYPE_EVENT_RECORD 19

1108 params.eventRecord.event = as_cu(event._h_event) 19

1109  

1110 _set_definition_node_params( 19

1111 self._h_node, &params, event_owner) 

1112 self._h_event = event._h_event 19

1113  

1114 @property 

1115 def event(self) -> Event: 

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

1117 return Event._from_handle(self._h_event) 2vgNbUf1cVfKc9 Q 'c

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) 2We*c,c.c:c=c@cXeYe2cWfKcLcX 6dSbM pc$f%f'fA (f)f*f+f,f-f.f/f

1134 n._h_node = h_node 2We*c,c.c:c=c@cXeYe2cWfKcLcX 6dSbM pc$f%f'fA (f)f*f+f,f-f.f/f

1135 n._h_event = h_event 2We*c,c.c:c=c@cXeYe2cWfKcLcX 6dSbM pc$f%f'fA (f)f*f+f,f-f.f/f

1136 return n 2We*c,c.c:c=c@cXeYe2cWfKcLcX 6dSbM pc$f%f'fA (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) 2Lc

1142 cdef cydriver.CUevent event 

1143 with nogil: 2Lc

1144 HANDLE_RETURN(cydriver.cuGraphEventWaitNodeGetEvent(node, &event)) 2Lc

1145 cdef EventHandle h_event = create_event_handle_ref(event) 2Lc

1146 return EventWaitNode._create_with_params(h_node, h_event) 2Lc

1147  

1148 def __repr__(self) -> str: 

1149 return (f"<EventWaitNode handle=0x{as_intptr(self._h_node):x}" 2lg

1150 f" event=0x{as_intptr(self._h_event):x}>") 2lg

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) 2X Sbpc

1155 Event_check_open(event) 2X pc

1156 cdef OpaqueHandle event_owner = event._h_event 1X

1157 cdef cydriver.CUgraphNodeParams params 

1158  

1159 c_memset(&params, 0, sizeof(params)) 1X

1160 params.type = cydriver.CU_GRAPH_NODE_TYPE_WAIT_EVENT 1X

1161 params.eventWait.event = as_cu(event._h_event) 1X

1162  

1163 _set_definition_node_params( 1X

1164 self._h_node, &params, event_owner) 

1165 self._h_event = event._h_event 1X

1166  

1167 @property 

1168 def event(self) -> Event: 

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

1170 return Event._from_handle(self._h_event) 2wgOb2cWfLcX M pc

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) 2~eafbfcfdfZeQbefffgfhfifjfkflfmfnfofpfqfrfsf] tfufvfwfL { 4d! 6 # $ % 7 ' ( IcJc^ xfrbyf| O zfHcU y 7d3 9 X + , Vd5d6dAf0e]cRbSb@e[eY K Q M V W 1 ; 'cpc)d*dR z 2 P 8d9dBfCfDfEfA FfGfHfIfJfKfLfMf

1188 n._h_node = h_node 2~eafbfcfdfZeQbefffgfhfifjfkflfmfnfofpfqfrfsf] tfufvfwfL { 4d! 6 # $ % 7 ' ( IcJc^ xfrbyf| O zfHcU y 7d3 9 X + , Vd5d6dAf0e]cRbSb@e[eY K Q M V W 1 ; 'cpc)d*dR z 2 P 8d9dBfCfDfEfA FfGfHfIfJfKfLfMf

1189 n._callable = callable_obj 2~eafbfcfdfZeQbefffgfhfifjfkflfmfnfofpfqfrfsf] tfufvfwfL { 4d! 6 # $ % 7 ' ( IcJc^ xfrbyf| O zfHcU y 7d3 9 X + , Vd5d6dAf0e]cRbSb@e[eY K Q M V W 1 ; 'cpc)d*dR z 2 P 8d9dBfCfDfEfA FfGfHfIfJfKfLfMf

1190 n._fn = fn 2~eafbfcfdfZeQbefffgfhfifjfkflfmfnfofpfqfrfsf] tfufvfwfL { 4d! 6 # $ % 7 ' ( IcJc^ xfrbyf| O zfHcU y 7d3 9 X + , Vd5d6dAf0e]cRbSb@e[eY K Q M V W 1 ; 'cpc)d*dR z 2 P 8d9dBfCfDfEfA FfGfHfIfJfKfLfMf

1191 n._user_data = user_data 2~eafbfcfdfZeQbefffgfhfifjfkflfmfnfofpfqfrfsf] tfufvfwfL { 4d! 6 # $ % 7 ' ( IcJc^ xfrbyf| O zfHcU y 7d3 9 X + , Vd5d6dAf0e]cRbSb@e[eY K Q M V W 1 ; 'cpc)d*dR z 2 P 8d9dBfCfDfEfA FfGfHfIfJfKfLfMf

1192 return n 2~eafbfcfdfZeQbefffgfhfifjfkflfmfnfofpfqfrfsf] tfufvfwfL { 4d! 6 # $ % 7 ' ( IcJc^ xfrbyf| O zfHcU y 7d3 9 X + , Vd5d6dAf0e]cRbSb@e[eY K Q M V W 1 ; 'cpc)d*dR z 2 P 8d9dBfCfDfEfA FfGfHfIfJfKfLfMf

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| O 3 RbSbK ;

1198 cdef cydriver.CUDA_HOST_NODE_PARAMS params 

1199 with nogil: 2Qb] L { ^ rb| O 3 RbSbK ;

1200 HANDLE_RETURN(cydriver.cuGraphHostNodeGetParams(node, &params)) 2Qb] L { ^ rb| O 3 RbSbK ;

1201  

1202 cdef object callable_obj = None 2Qb] L { ^ rb| O 3 RbSbK ;

1203 if _is_py_host_trampoline(params.fn): 2Qb] L { ^ rb| O 3 RbSbK ;

1204 callable_obj = <object>params.userData 2Qb] L { ^ rb| O 3 RbSbK ;

1205  

1206 return HostCallbackNode._create_with_params( 2Qb] L { ^ rb| O 3 RbSbK ;

1207 h_node, callable_obj, params.fn, params.userData) 2Qb] L { ^ rb| O 3 RbSbK ;

1208  

1209 def __repr__(self) -> str: 

1210 if self._callable is not None: 27dP :f

1211 name = getattr(self._callable, '__name__', '?') 2P :f

1212 return (f"<HostCallbackNode handle=0x{as_intptr(self._h_node):x}" 2P :f

1213 f" callback={name}>") 2P :f

1214 return (f"<HostCallbackNode handle=0x{as_intptr(self._h_node):x}" 27d

1215 f" cfunc=0x{<uintptr_t>self._fn:x}>") 27d

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

1224  

1225 .. warning:: 

1226  

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

1228 deadlock or corrupt driver state. 

1229  

1230 Use caution when a Python callback retains an object that owns a 

1231 graph. Any reference cycle involving the callback and a graph that 

1232 retains it cannot be broken by Python's cyclic garbage collector. 

1233 Use a weak reference to break such cycles. 

1234 """ 

1235 GN_check_valid(self) 2Ze+ , 0e@e[e)d*d

1236 cdef cydriver.CUhostFn c_fn 

1237 cdef void* c_user_data 

1238 cdef OpaqueHandle fn_owner, data_owner 

1239 cdef cydriver.CUgraphNodeParams params 

1240  

1241 _resolve_host_callback( 2Ze+ , 0e)d*d

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

1243 c_memset(&params, 0, sizeof(params)) 1+,

1244 params.type = cydriver.CU_GRAPH_NODE_TYPE_HOST 1+,

1245 params.host.fn = c_fn 1+,

1246 params.host.userData = c_user_data 1+,

1247  

1248 _set_definition_node_params( 1+,

1249 self._h_node, &params, fn_owner, data_owner) 

1250 self._callable = fn if _is_py_host_trampoline(c_fn) else None 1+,

1251 self._fn = c_fn 1+,

1252 self._user_data = c_user_data 1+,

1253  

1254 @property 

1255 def callback(self): 

1256 """The Python callable, or None for ctypes function pointer callbacks.""" 

1257 return self._callable 2xgygL 7d3 + , K V W ; )d*d

1258  

1259  

1260cdef class ConditionalNode(GraphNode): 

1261 """Base class for conditional nodes. 

1262  

1263 When created via builder methods (if_then, if_else, while_loop, switch), 

1264 a specific subclass (IfNode, IfElseNode, WhileNode, SwitchNode) is 

1265 returned. When reconstructed from the driver on CUDA 13.2+, the 

1266 correct subclass is determined via cuGraphNodeGetParams. On older 

1267 drivers, this base class is used as a fallback. 

1268  

1269 Properties 

1270 ---------- 

1271 condition : GraphCondition or None 

1272 The condition variable controlling execution (None pre-13.2). 

1273 cond_type : str or None 

1274 The conditional type ("if", "while", or "switch"; None pre-13.2). 

1275 branches : tuple of GraphDefinition 

1276 The body graphs for each branch (empty pre-13.2). 

1277 """ 

1278  

1279 @staticmethod 

1280 cdef ConditionalNode _create_from_driver(GraphNodeHandle h_node): 

1281 cdef ConditionalNode n 

1282 if not _check_node_get_params(): 1!6#$%7'(@

1283 n = ConditionalNode.__new__(ConditionalNode) 

1284 n._h_node = h_node 

1285 n._condition = None 

1286 n._cond_type = cydriver.CU_GRAPH_COND_TYPE_IF 

1287 n._branches = () 

1288 return n 

1289 IF CUDA_CORE_BUILD_MAJOR >= 13: 

1290 return ConditionalNode._create_from_driver_params(h_node) 1!6#$%7'(@

1291 ELSE: 

1292 raise AssertionError("unreachable: cuGraphNodeGetParams needs the CUDA 13 build") 

1293  

1294 IF CUDA_CORE_BUILD_MAJOR >= 13: 

1295 @staticmethod 

1296 cdef ConditionalNode _create_from_driver_params(GraphNodeHandle h_node): 

1297 cdef ConditionalNode n 

1298 cdef cydriver.CUgraphNode node = as_cu(h_node) 1!6#$%7'(@

1299 cdef cydriver.CUgraphNodeParams params 

1300 _node_get_params(node, &params) 1!6#$%7'(@

1301 cdef int cond_type_int = <int>params.conditional.type 1!6#$%7'(@

1302 cdef unsigned int size = params.conditional.size 1!6#$%7'(@

1303  

1304 cdef GraphCondition condition = GraphCondition.__new__(GraphCondition) 1!6#$%7'(@

1305 condition._c_handle = params.conditional.handle 1!6#$%7'(@

1306  

1307 cdef GraphHandle h_graph = graph_node_get_graph(h_node) 1!6#$%7'(@

1308 cdef list branch_list = [] 1!6#$%7'(@

1309 cdef unsigned int i 

1310 cdef GraphHandle h_branch 

1311 if params.conditional.phGraph_out != NULL: 1!6#$%7'(@

1312 for i in range(size): 1!6#$%7'(@

1313 h_branch = create_child_graph_handle( 1!6#$%7'(@

1314 params.conditional.phGraph_out[i], h_graph, node) 

1315 branch_list.append(GraphDefinition._from_handle(h_branch)) 1!6#$%7'(@

1316 cdef tuple branches = tuple(branch_list) 1!6#$%7'(@

1317  

1318 cdef type cls 

1319 if cond_type_int == <int>cydriver.CU_GRAPH_COND_TYPE_IF: 1!6#$%7'(@

1320 if size == 1: 1!6%7

1321 cls = IfNode 1!%

1322 else: 

1323 cls = IfElseNode 167

1324 elif cond_type_int == <int>cydriver.CU_GRAPH_COND_TYPE_WHILE: 1#$'(@

1325 cls = WhileNode 1$(@

1326 else: 

1327 cls = SwitchNode 1#'

1328  

1329 n = cls.__new__(cls) 1!6#$%7'(@

1330 n._h_node = h_node 1!6#$%7'(@

1331 n._condition = condition 1!6#$%7'(@

1332 n._cond_type = <cydriver.CUgraphConditionalNodeType>cond_type_int 1!6#$%7'(@

1333 n._branches = branches 1!6#$%7'(@

1334 return n 1!6#$%7'(@

1335  

1336 def __repr__(self) -> str: 

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

1338  

1339 @property 

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

1341 """The condition variable controlling execution.""" 

1342 return self._condition 2]eNfXfOf^ePfYfQf

1343  

1344 @property 

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

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

1347  

1348 Returns None when reconstructed from the driver pre-CUDA 13.2, 

1349 as the conditional type cannot be determined. 

1350 """ 

1351 if self._condition is None: 2]eNfXfOf^ePfYfQf

1352 return None 

1353 if self._cond_type == cydriver.CU_GRAPH_COND_TYPE_IF: 2]eNfXfOf^ePfYfQf

1354 return GraphConditionalType("if") 2]eNf^ePf

1355 elif self._cond_type == cydriver.CU_GRAPH_COND_TYPE_WHILE: 

1356 return GraphConditionalType("while") 2OfQf

1357 else: 

1358 return GraphConditionalType("switch") 2XfYf

1359  

1360 @property 

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

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

1363  

1364 Returns an empty tuple when reconstructed from the driver 

1365 pre-CUDA 13.2. 

1366 """ 

1367 return self._branches 2]eNfXfOf^ePfYfQfzgBc# ' @

1368  

1369  

1370cdef class IfNode(ConditionalNode): 

1371 """An if-conditional node.""" 

1372  

1373 def __repr__(self) -> str: 

1374 return (f"<IfNode handle=0x{as_intptr(self._h_node):x}" 2mg

1375 f" condition=0x{<unsigned long long>self._condition._c_handle:x}>") 2mg

1376  

1377 @property 

1378 def then(self) -> GraphDefinition: 

1379 """The 'then' branch graph.""" 

1380 return self._branches[0] 2NfPfAgAc! %

1381  

1382  

1383cdef class IfElseNode(ConditionalNode): 

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

1385  

1386 def __repr__(self) -> str: 

1387 return (f"<IfElseNode handle=0x{as_intptr(self._h_node):x}" 2ng

1388 f" condition=0x{<unsigned long long>self._condition._c_handle:x}>") 2ng

1389  

1390 @property 

1391 def then(self) -> GraphDefinition: 

1392 """The ``then`` branch graph (executed when condition is non-zero).""" 

1393 return self._branches[0] 2]e^eogqc6 7

1394  

1395 @property 

1396 def else_(self) -> GraphDefinition: 

1397 """The ``else`` branch graph (executed when condition is zero).""" 

1398 return self._branches[1] 2]e^eogqc6 7

1399  

1400  

1401cdef class WhileNode(ConditionalNode): 

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

1403  

1404 def __repr__(self) -> str: 

1405 return (f"<WhileNode handle=0x{as_intptr(self._h_node):x}" 2pg

1406 f" condition=0x{<unsigned long long>self._condition._c_handle:x}>") 2pg

1407  

1408 @property 

1409 def body(self) -> GraphDefinition: 

1410 """The loop body graph.""" 

1411 return self._branches[0] 2OfQfBgCc$ (

1412  

1413  

1414cdef class SwitchNode(ConditionalNode): 

1415 """A switch conditional node.""" 

1416  

1417 def __repr__(self) -> str: 

1418 return (f"<SwitchNode handle=0x{as_intptr(self._h_node):x}" 2qg

1419 f" condition=0x{<unsigned long long>self._condition._c_handle:x}>") 2qg

1420  

1421  

1422cdef class ExecutableGraphNode: 

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

1424  

1425 Create executable-node views with ``graph[node]``. CUDA validates that the 

1426 node identifies a node in the executable graph when an operation is 

1427 performed. 

1428 """ 

1429  

1430 def __init__(self): 

1431 raise RuntimeError( 2Cg

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

1433  

1434 def __repr__(self) -> str: 

1435 return ( 2Tb

1436 f"<{type(self).__name__} graph=0x{as_intptr(self._h_graph_exec):x}" 2Tb

1437 f" node=0x{as_intptr(self._h_node):x}>" 2Tb

1438 ) 

1439  

1440  

1441cdef class ExecutableKernelNode(ExecutableGraphNode): 

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

1443  

1444 def update( 

1445 self, 

1446 *, 

1447 LaunchConfig config not None: LaunchConfig, 

1448 Kernel kernel not None: Kernel, 

1449 args, 

1450 ) -> None: 

1451 """Replace all kernel launch parameters for future launches. 

1452  

1453 ``args`` must contain the complete argument sequence; use ``args=()`` 

1454 for a no-argument kernel. Clustered and cooperative launch 

1455 configurations are not supported. 

1456 """ 

1457 cdef LaunchConfig c_config = config 2y N JbKbB C D z J

1458 cdef Kernel c_kernel = kernel 2y N JbKbB C D z J

1459 cdef ParamHolder arg_holder 

1460 cdef object kernel_args 

1461 cdef OpaqueHandle kernel_owner = c_kernel._h_kernel 2y N JbKbB C D z J

1462 cdef OpaqueHandle args_owner 

1463 cdef cydriver.CUgraphNodeParams params 

1464  

1465 if c_config.cluster is not None or c_config.is_cooperative: 2y N JbKbB C D z J

1466 raise NotImplementedError( 2JbKb

1467 "updating clustered or cooperative kernel nodes is not " 

1468 "supported") 

1469 arg_holder = ParamHolder(args) 1yNBCDzJ

1470  

1471 c_memset(&params, 0, sizeof(params)) 1yNBCDzJ

1472 params.type = cydriver.CU_GRAPH_NODE_TYPE_KERNEL 1yNBCDzJ

1473 params.kernel.kern = as_cu(c_kernel._h_kernel) 1yNBCDzJ

1474 params.kernel.func = <cydriver.CUfunction>NULL 1yNBCDzJ

1475 params.kernel.gridDimX = c_config.grid[0] 1yNBCDzJ

1476 params.kernel.gridDimY = c_config.grid[1] 1yNBCDzJ

1477 params.kernel.gridDimZ = c_config.grid[2] 1yNBCDzJ

1478 params.kernel.blockDimX = c_config.block[0] 1yNBCDzJ

1479 params.kernel.blockDimY = c_config.block[1] 1yNBCDzJ

1480 params.kernel.blockDimZ = c_config.block[2] 1yNBCDzJ

1481 params.kernel.sharedMemBytes = c_config.shmem_size 1yNBCDzJ

1482 params.kernel.kernelParams = <void**><uintptr_t>arg_holder.ptr 1yNBCDzJ

1483 params.kernel.extra = NULL 1yNBCDzJ

1484 params.kernel.ctx = <cydriver.CUcontext>NULL 1yNBCDzJ

1485  

1486 kernel_args = arg_holder.kernel_args 1yNBCDzJ

1487 if kernel_args is not None: 1yNBCDzJ

1488 args_owner = make_opaque_py(kernel_args) 1yBCzJ

1489 _set_executable_node_params( 1yNBCDzJ

1490 self._h_graph_exec, self._h_node, &params, 

1491 kernel_owner, args_owner) 

1492  

1493 @property 

1494 def is_enabled(self) -> bool: 

1495 """Whether this node is enabled in the executable graph.""" 

1496 return _get_executable_node_enabled( 1}5

1497 self._h_graph_exec, self._h_node) 1}5

1498  

1499 def enable(self) -> None: 

1500 """Enable this node in the executable graph.""" 

1501 _set_executable_node_enabled( 1~5

1502 self._h_graph_exec, self._h_node, True) 

1503  

1504 def disable(self) -> None: 

1505 """Disable this node in the executable graph.""" 

1506 _set_executable_node_enabled( 15

1507 self._h_graph_exec, self._h_node, False) 

1508  

1509  

1510cdef class ExecutableMemsetNode(ExecutableGraphNode): 

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

1512  

1513 def update( 

1514 self, 

1515 *, 

1516 dst: Buffer | int, 

1517 value, 

1518 size_t width, 

1519 size_t height=1, 

1520 size_t pitch=0, 

1521 ) -> None: 

1522 """Replace all memset parameters for future launches.""" 

1523 cdef cydriver.CUdeviceptr c_dst 

1524 cdef OpaqueHandle dst_owner = _resolve_memcpy_operand( 1EF

1525 dst, None, "dst", &c_dst) 

1526 cdef unsigned int c_value 

1527 cdef unsigned int element_size 

1528 c_value, element_size = _parse_fill_value(value) 1EF

1529  

1530 cdef cydriver.CUcontext ctx = NULL 1EF

1531 cdef cydriver.CUgraphNodeParams params 

1532 with nogil: 1EF

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

1534  

1535 c_memset(&params, 0, sizeof(params)) 1EF

1536 params.type = cydriver.CU_GRAPH_NODE_TYPE_MEMSET 1EF

1537 params.memset.dst = c_dst 1EF

1538 params.memset.value = c_value 1EF

1539 params.memset.elementSize = element_size 1EF

1540 params.memset.width = width 1EF

1541 params.memset.height = height 1EF

1542 params.memset.pitch = pitch 1EF

1543 params.memset.ctx = ctx 1EF

1544 _set_executable_node_params( 1EF

1545 self._h_graph_exec, self._h_node, &params, dst_owner) 

1546  

1547 @property 

1548 def is_enabled(self) -> bool: 

1549 """Whether this node is enabled in the executable graph.""" 

1550 return _get_executable_node_enabled( 10

1551 self._h_graph_exec, self._h_node) 10

1552  

1553 def enable(self) -> None: 

1554 """Enable this node in the executable graph.""" 

1555 _set_executable_node_enabled( 10

1556 self._h_graph_exec, self._h_node, True) 

1557  

1558 def disable(self) -> None: 

1559 """Disable this node in the executable graph.""" 

1560 _set_executable_node_enabled( 10

1561 self._h_graph_exec, self._h_node, False) 

1562  

1563  

1564cdef class ExecutableMemcpyNode(ExecutableGraphNode): 

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

1566  

1567 def update( 

1568 self, 

1569 *, 

1570 dst: Buffer | int, 

1571 src: Buffer | int, 

1572 size_t size, 

1573 ) -> None: 

1574 """Replace all one-dimensional memcpy parameters for future launches. 

1575  

1576 Nodes recorded by stream capture are supported. 

1577 """ 

1578 cdef cydriver.CUdeviceptr c_dst 

1579 cdef cydriver.CUdeviceptr c_src 

1580 cdef OpaqueHandle dst_owner = _resolve_memcpy_operand( 1uGHIab

1581 dst, None, "dst", &c_dst) 

1582 cdef OpaqueHandle src_owner = _resolve_memcpy_operand( 1uGHIab

1583 src, None, "src", &c_src) 

1584 cdef cydriver.CUmemorytype dst_type 

1585 cdef cydriver.CUmemorytype src_type 

1586 cdef cydriver.CUcontext ctx = NULL 1uGHIab

1587 cdef cydriver.CUgraphNodeParams params 

1588 cdef cydriver.CUDA_MEMCPY3D recorded 

1589 cdef cydriver.CUgraphNode node = as_cu(self._h_node) 1uGHIab

1590  

1591 c_memset(&params, 0, sizeof(params)) 1uGHIab

1592 params.type = cydriver.CU_GRAPH_NODE_TYPE_MEMCPY 1uGHIab

1593 _init_memcpy_params( 1uGHIab

1594 c_dst, c_src, size, &params.memcpy.copyParams, 

1595 &dst_type, &src_type) 

1596 # A destroyed node is reported by _set_executable_node_params below. 

1597 # The memory types are read from the definition node, not from the 

1598 # instantiated graph. That is correct only while MemcpyNode.update() 

1599 # keeps a unified operand unified, which it does; an executable update 

1600 # rejects a change of memory type. 

1601 if node != NULL: 1uGHIab

1602 with nogil: 1uGHIab

1603 HANDLE_RETURN(cydriver.cuGraphMemcpyNodeGetParams( 1uGHIab

1604 node, &recorded)) 

1605 if recorded.dstMemoryType == cydriver.CU_MEMORYTYPE_UNIFIED: 1uGHIab

1606 params.memcpy.copyParams.dstMemoryType = ( 1uab

1607 cydriver.CU_MEMORYTYPE_UNIFIED) 

1608 params.memcpy.copyParams.dstHost = NULL 1uab

1609 params.memcpy.copyParams.dstDevice = c_dst 1uab

1610 if recorded.srcMemoryType == cydriver.CU_MEMORYTYPE_UNIFIED: 1uGHIab

1611 params.memcpy.copyParams.srcMemoryType = ( 1uab

1612 cydriver.CU_MEMORYTYPE_UNIFIED) 

1613 params.memcpy.copyParams.srcHost = NULL 1uab

1614 params.memcpy.copyParams.srcDevice = c_src 1uab

1615 with nogil: 1uGHIab

1616 HANDLE_RETURN(cydriver.cuCtxGetCurrent(&ctx)) 1uGHIab

1617 params.memcpy.copyCtx = ctx 1uGHIab

1618 _set_executable_node_params( 1uGHIab

1619 self._h_graph_exec, self._h_node, &params, 

1620 dst_owner, src_owner) 

1621  

1622 @property 

1623 def is_enabled(self) -> bool: 

1624 """Whether this node is enabled in the executable graph.""" 

1625 return _get_executable_node_enabled( 1Z

1626 self._h_graph_exec, self._h_node) 1Z

1627  

1628 def enable(self) -> None: 

1629 """Enable this node in the executable graph.""" 

1630 _set_executable_node_enabled( 1Z

1631 self._h_graph_exec, self._h_node, True) 

1632  

1633 def disable(self) -> None: 

1634 """Disable this node in the executable graph.""" 

1635 _set_executable_node_enabled( 1Z

1636 self._h_graph_exec, self._h_node, False) 

1637  

1638  

1639cdef class ExecutableChildGraphNode(ExecutableGraphNode): 

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

1641  

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

1643 """Replace the embedded graph parameters for future launches.""" 

1644 GD_check_valid(child) 1UK

1645 cdef cydriver.CUgraphNodeParams params 

1646 c_memset(&params, 0, sizeof(params)) 1UK

1647 params.type = cydriver.CU_GRAPH_NODE_TYPE_GRAPH 1UK

1648 params.graph.graph = as_cu(child._h_graph) 1UK

1649 _set_executable_node_params( 1UK

1650 self._h_graph_exec, self._h_node, &params) 

1651  

1652  

1653cdef class ExecutableEventRecordNode(ExecutableGraphNode): 

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

1655  

1656 def update(self, Event event not None: Event) -> None: 

1657 """Replace the event recorded by future launches.""" 

1658 Event_check_open(event) 1Q

1659 cdef OpaqueHandle event_owner = event._h_event 1Q

1660 cdef cydriver.CUgraphNodeParams params 

1661 c_memset(&params, 0, sizeof(params)) 1Q

1662 params.type = cydriver.CU_GRAPH_NODE_TYPE_EVENT_RECORD 1Q

1663 params.eventRecord.event = as_cu(event._h_event) 1Q

1664 _set_executable_node_params( 1Q

1665 self._h_graph_exec, self._h_node, &params, event_owner) 

1666  

1667  

1668cdef class ExecutableEventWaitNode(ExecutableGraphNode): 

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

1670  

1671 def update(self, Event event not None: Event) -> None: 

1672 """Replace the event waited on by future launches.""" 

1673 Event_check_open(event) 1M

1674 cdef OpaqueHandle event_owner = event._h_event 1M

1675 cdef cydriver.CUgraphNodeParams params 

1676 c_memset(&params, 0, sizeof(params)) 1M

1677 params.type = cydriver.CU_GRAPH_NODE_TYPE_WAIT_EVENT 1M

1678 params.eventWait.event = as_cu(event._h_event) 1M

1679 _set_executable_node_params( 1M

1680 self._h_graph_exec, self._h_node, &params, event_owner) 

1681  

1682  

1683cdef class ExecutableHostCallbackNode(ExecutableGraphNode): 

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

1685  

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

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

1688  

1689 ``fn`` may be a Python callable, or a ctypes function pointer whose 

1690 declared prototype matches ``CUhostFn`` (``void (*)(void*)``); a 

1691 mismatched prototype raises ``TypeError``. 

1692  

1693 .. warning:: 

1694  

1695 Callbacks must not call CUDA API functions. Doing so may deadlock 

1696 or corrupt driver state. 

1697 """ 

1698 cdef cydriver.CUhostFn c_fn 

1699 cdef void* c_user_data 

1700 cdef OpaqueHandle fn_owner 

1701 cdef OpaqueHandle data_owner 

1702 cdef cydriver.CUgraphNodeParams params 

1703  

1704 _resolve_host_callback( 1YVW1R2P

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

1706 c_memset(&params, 0, sizeof(params)) 1YVW1R2P

1707 params.type = cydriver.CU_GRAPH_NODE_TYPE_HOST 1YVW1R2P

1708 params.host.fn = c_fn 1YVW1R2P

1709 params.host.userData = c_user_data 1YVW1R2P

1710 _set_executable_node_params( 1YVW1R2P

1711 self._h_graph_exec, self._h_node, &params, 

1712 fn_owner, data_owner) 

1713  

1714  

1715cdef ExecutableGraphNode create_executable_node_view( 

1716 const GraphExecHandle& h_exec, 

1717 GraphNode node): 

1718 cdef type view_type 

1719 if isinstance(node, KernelNode): 2U y Y ~ } N JbKbu 5 Z 0 TbK Q M V W B C D G H I E F Lb1 R z a b J 2 P

1720 view_type = ExecutableKernelNode 2y ~ } N JbKb5 TbB C D z J

1721 elif isinstance(node, MemsetNode): 2U Y u Z 0 K Q M V W G H I E F Lb1 R a b 2 P

1722 view_type = ExecutableMemsetNode 10EF

1723 elif isinstance(node, MemcpyNode): 2U Y u Z K Q M V W G H I Lb1 R a b 2 P

1724 view_type = ExecutableMemcpyNode 1uZGHIab

1725 elif isinstance(node, ChildGraphNode): 2U Y K Q M V W Lb1 R 2 P

1726 view_type = ExecutableChildGraphNode 1UK

1727 elif isinstance(node, EventRecordNode): 2Y Q M V W Lb1 R 2 P

1728 view_type = ExecutableEventRecordNode 1Q

1729 elif isinstance(node, EventWaitNode): 2Y M V W Lb1 R 2 P

1730 view_type = ExecutableEventWaitNode 1M

1731 elif isinstance(node, HostCallbackNode): 2Y V W Lb1 R 2 P

1732 view_type = ExecutableHostCallbackNode 1YVW1R2P

1733 else: 

1734 raise TypeError( 2Lb

1735 f"{type(node).__name__} does not support executable updates") 2Lb

1736  

1737 if as_cu(h_exec) == NULL: 2U y Y ~ } N JbKbu 5 Z 0 TbK Q M V W B C D G H I E F 1 R z a b J 2 P

1738 raise ValueError("executable graph has been closed") 

1739 if as_cu(node._h_node) == NULL: 2U y Y ~ } N JbKbu 5 Z 0 TbK Q M V W B C D G H I E F 1 R z a b J 2 P

1740 raise ValueError("source graph node is no longer valid") 

1741  

1742 cdef ExecutableGraphNode view = view_type.__new__(view_type) 2U y Y ~ } N JbKbu 5 Z 0 TbK Q M V W B C D G H I E F 1 R z a b J 2 P

1743 view._h_graph_exec = h_exec 2U y Y ~ } N JbKbu 5 Z 0 TbK Q M V W B C D G H I E F 1 R z a b J 2 P

1744 view._h_node = node._h_node 2U y Y ~ } N JbKbu 5 Z 0 TbK Q M V W B C D G H I E F 1 R z a b J 2 P

1745 return view 2U y Y ~ } N JbKbu 5 Z 0 TbK Q M V W B C D G H I E F 1 R z a b J 2 P