Build WHILE graph using an existing captured graph as the iteration body
| 195 | |
| 196 | // Build WHILE graph using an existing captured graph as the iteration body |
| 197 | void Build(cudaGraph_t iteration_graph, double* rz_dev_ptr, double tol, int* iter_count, int maxsteps) |
| 198 | { |
| 199 | capture_ok = false; |
| 200 | ngla::EnsureCuBlasWorkspace(); |
| 201 | |
| 202 | // 1. Create outer graph |
| 203 | cudaGraphCreate(&outer_graph, 0); |
| 204 | |
| 205 | // 2. Create conditional handle with default=1 (do-while) |
| 206 | cudaGraphConditionalHandleCreate(&handle, outer_graph, 1, |
| 207 | cudaGraphCondAssignDefault); |
| 208 | |
| 209 | // // 3. Add WHILE node |
| 210 | // cudaGraphNode_t while_node; |
| 211 | // cudaGraphNodeParams cParams = {}; |
| 212 | // cParams.type = cudaGraphNodeTypeConditional; |
| 213 | // cParams.conditional.handle = handle; |
| 214 | // cParams.conditional.type = cudaGraphCondTypeWhile; |
| 215 | // cParams.conditional.size = 1; |
| 216 | |
| 217 | |
| 218 | // // 6-arg pDependencyData variant exists only in CUDA 12.3–12.8; 12.9+ reverts to 5-arg |
| 219 | // #if CUDART_VERSION >= 12030 && CUDART_VERSION < 12090 |
| 220 | // cudaGraphAddNode(&while_node, outer_graph, nullptr, nullptr, 0, &cParams); |
| 221 | // #else |
| 222 | // cudaGraphAddNode(&while_node, outer_graph, nullptr, 0, &cParams); |
| 223 | // #endif |
| 224 | // body_graph = cParams.conditional.phGraph_out[0]; |
| 225 | |
| 226 | // // 4. Add iteration body as child graph node in body |
| 227 | // // Child graphs ARE allowed in conditional bodies |
| 228 | // cudaGraphNode_t child_node; |
| 229 | // auto err = cudaGraphAddChildGraphNode(&child_node, body_graph, nullptr, 0, iteration_graph); |
| 230 | // if (err != cudaSuccess) |
| 231 | // throw ngstd::Exception( |
| 232 | // std::string("[CudaWhileGraph] cudaGraphAddChildGraphNode FAILED: ") |
| 233 | // + cudaGetErrorString(err)); |
| 234 | |
| 235 | // 3. Add WHILE node |
| 236 | cudaGraphNode_t while_node; |
| 237 | cudaGraphNodeParams cParams = {}; |
| 238 | cParams.type = cudaGraphNodeTypeConditional; |
| 239 | cParams.conditional.handle = handle; |
| 240 | cParams.conditional.type = cudaGraphCondTypeWhile; |
| 241 | cParams.conditional.size = 1; |
| 242 | #if CUDART_VERSION < 13000 |
| 243 | cudaGraphAddNode_v2(&while_node, outer_graph, nullptr, nullptr, 0, &cParams); |
| 244 | #else |
| 245 | cudaGraphAddNode(&while_node, outer_graph, nullptr, nullptr, 0, &cParams); |
| 246 | #endif |
| 247 | body_graph = cParams.conditional.phGraph_out[0]; |
| 248 | |
| 249 | // 4. Add iteration body as child graph node in body |
| 250 | // Child graphs ARE allowed in conditional bodies |
| 251 | cudaGraphNode_t child_node; |
| 252 | #if CUDART_VERSION >= 12030 |
| 253 | auto err = cudaGraphAddChildGraphNode(&child_node, body_graph, nullptr, 0, iteration_graph); |
| 254 | #else |
no test coverage detected