validate_outputs(roots, const_cast(inputs),  {
    return msg;
  });
// Checks
auto graph_task = std::make_shared(
      / keep_graph / keep_graph,
      / create_graph / create_graph,
      / depth / not_reentrant_backward_call ? 0 : total_depth + 1,
      / cpu_ready_queue / local_ready_queue);
// If we receive a single root, skip creating extra root node
  // …
  // Prepare graph by computing dependencies
  // …
  // Queue the root 
  // …
  // launch execution
  // …
}

After creating the `GraphTask`, we use its associated function if we only have one root node. If we have multiple root nodes, we create a special `GraphRoot` object as described before.

```c++
  bool skip_dummy_node = roots.size() == 1;
  auto graph_root = skip_dummy_node ?
    roots.at(0).function :
    std::make_shared<GraphRoot>(roots, inputs);

