@@ -394,12 +394,12 @@ sycl_ext::command_graph myGraph(myContext, myDevice);
394394
395395int myScalar = 42;
396396// Create graph dynamic parameters
397- dynamic_parameter dynParamInput(myGraph, ptrX);
398- dynamic_parameter dynParamScalar(myGraph, myScalar);
397+ sycl_ext:: dynamic_parameter dynParamInput(myGraph, ptrX);
398+ sycl_ext:: dynamic_parameter dynParamScalar(myGraph, myScalar);
399399
400400// The node uses ptrX as an input & output parameter, with operand
401401// mySclar as another argument.
402- node kernelNode = myGraph.add([&](handler& cgh) {
402+ sycl_ext:: node kernelNode = myGraph.add([&](handler& cgh) {
403403 cgh.set_args(dynParamInput, ptrY, dynParamScalar);
404404 cgh.parallel_for(range {n}, builtinKernel);
405405});
@@ -438,9 +438,9 @@ sycl::buffer bufferB{...};
438438
439439// Create graph dynamic parameter using a placeholder accessor, since the
440440// sycl::handler is not available here outside of the command-group scope.
441- dynamic_parameter dynParamAccessor(myGraph, bufferA.get_access());
441+ sycl_ext:: dynamic_parameter dynParamAccessor(myGraph, bufferA.get_access());
442442
443- node kernelNode = myGraph.add([ &] (handler& cgh) {
443+ sycl_ext:: node kernelNode = myGraph.add([ &] (handler& cgh) {
444444 // Require the accessor contained in the dynamic paramter
445445 cgh.require(dynParamAccessor);
446446 // Set the arg on the kernel using the dynamic parameter directly
@@ -453,6 +453,121 @@ node kernelNode = myGraph.add([&](handler& cgh) {
453453dynParamAccessor.update(bufferB.get_access());
454454```
455455
456+ ### Dynamic Command Groups
457+
458+ Example showing how a graph with a dynamic command group node can be updated.
459+
460+ ``` cpp
461+ ...
462+ using namespace sycl ;
463+ namespace sycl_ext = sycl::ext::oneapi::experimental;
464+
465+ queue Queue{};
466+ sycl_ext::command_graph Graph{Queue.get_context(), Queue.get_device()};
467+
468+ int * PtrA = malloc_device<int >(1024, Queue);
469+ int * PtrB = malloc_device<int >(1024, Queue);
470+
471+ auto CgfA = [ &] (handler &cgh) {
472+ cgh.parallel_for(1024, [ =] (item<1> Item) {
473+ PtrA[ Item.get_id()] = 1;
474+ });
475+ };
476+
477+ auto CgfB = [ &] (handler &cgh) {
478+ cgh.parallel_for(512, [ =] (item<1> Item) {
479+ PtrB[ Item.get_id()] = 2;
480+ });
481+ };
482+
483+ // Construct a dynamic command-group with CgfA as the active cgf (index 0).
484+ auto DynamicCG = sycl_ext::dynamic_command_group(Graph, {CgfA, CgfB});
485+
486+ // Create a dynamic command-group graph node.
487+ auto DynamicCGNode = Graph.add(DynamicCG);
488+
489+ auto ExecGraph = Graph.finalize(sycl_ext::property::graph::updatable{});
490+
491+ // The graph will execute CgfA.
492+ Queue.ext_oneapi_graph(ExecGraph).wait();
493+
494+ // Sets CgfB as active in the dynamic command-group (index 1).
495+ DynamicCG.set_active_index(1);
496+
497+ // Calls update to update the executable graph node with the changes to DynamicCG.
498+ ExecGraph.update(DynamicCGNode);
499+
500+ // The graph will execute CgfB.
501+ Queue.ext_oneapi_graph(ExecGraph).wait();
502+ ```
503+
504+ ### Dynamic Command Groups With Dynamic Parameters
505+
506+ Example showing how a graph with a dynamic command group that uses dynamic
507+ parameters in a node can be updated.
508+
509+ ```cpp
510+ ...
511+ using namespace sycl;
512+ namespace sycl_ext = sycl::ext::oneapi::experimental;
513+
514+ size_t N = 1024;
515+ queue Queue{};
516+ auto MyContext = Queue.get_context();
517+ auto MyDevice = Queue.get_device();
518+ sycl_ext::command_graph Graph{MyContext, MyDevice};
519+
520+ int *PtrA = malloc_device<int>(N, Queue);
521+ int *PtrB = malloc_device<int>(N, Queue);
522+
523+ // Kernels loaded from kernel bundle
524+ const std::vector<kernel_id> BuiltinKernelIds =
525+ MyDevice.get_info<info::device::built_in_kernel_ids>();
526+ kernel_bundle<bundle_state::executable> MyBundle =
527+ get_kernel_bundle<sycl::bundle_state::executable>(MyContext, { MyDevice }, BuiltinKernelIds);
528+
529+ kernel BuiltinKernelA = MyBundle.get_kernel(BuiltinKernelIds[0]);
530+ kernel BuiltinKernelB = MyBundle.get_kernel(BuiltinKernelIds[1]);
531+
532+ // Create a dynamic parameter with an initial value of PtrA
533+ sycl_ext::dynamic_parameter DynamicPointerArg{Graph, PtrA};
534+
535+ // Create command groups for both kernels which use DynamicPointerArg
536+ auto CgfA = [&](handler &cgh) {
537+ cgh.set_arg(0, DynamicPointerArg);
538+ cgh.parallel_for(range {N}, BuiltinKernelA);
539+ };
540+
541+ auto CgfB = [&](handler &cgh) {
542+ cgh.set_arg(0, DynamicPointerArg);
543+ cgh.parallel_for(range {N / 2}, BuiltinKernelB);
544+ };
545+
546+ // Construct a dynamic command-group with CgfA as the active cgf (index 0).
547+ auto DynamicCG = sycl_ext::dynamic_command_group(Graph, {CgfA, CgfB});
548+
549+ // Create a dynamic command-group graph node.
550+ auto DynamicCGNode = Graph.add(DynamicCG);
551+
552+ auto ExecGraph = Graph.finalize(sycl_ext::property::graph::updatable{});
553+
554+ // The graph will execute CgfA with PtrA.
555+ Queue.ext_oneapi_graph(ExecGraph).wait();
556+
557+ //Update DynamicPointerArg with a new value
558+ DynamicPointerArg.update(PtrB);
559+
560+ // Sets CgfB as active in the dynamic command-group (index 1).
561+ DynamicCG.set_active_index(1);
562+
563+ // Calls update to update the executable graph node with the changes to
564+ // DynamicCG and DynamicPointerArg.
565+ ExecGraph.update(DynamicCGNode);
566+
567+ // The graph will execute CgfB with PtrB.
568+ Queue.ext_oneapi_graph(ExecGraph).wait();
569+ ```
570+
456571### Whole Graph Update
457572
458573Example that shows recording and updating several nodes with different
0 commit comments