code: def graph_metrics(dependencies, dependents, total_dependencies):
      r"""Useful measures of a graph used by ``flash.core.serve.dag.order.order``
  
      Example DAG (a1 has no dependencies; b2 and c1 are root nodes):
  
      c1
      |
      b1  b2
       \  /
        a1
  
      For each key we return:
      1.  The number of keys that can only be run after this key is
          run.  The root nodes have value 1 while deep child nodes
          will have larger values.
  
          1
          |
          2   1
           \ /
            4
  
      2.  The minimum value of the total number of dependencies of
          all final dependents (see module-level comment for more).
          In other words, the minimum of ``ndependencies`` of root
          nodes connected to the current node.
  
          3
          |
          3   2
           \ /
            2
  
      3.  The maximum value of the total number of dependencies of
          all final dependents (see module-level comment for more).
          In other words, the maximum of ``ndependencies`` of root
          nodes connected to the current node.
  
          3
          |
          3   2
           \ /
            3
  
      4.  The minimum height from a root node
  
          0
          |
          1   0
           \ /
            1
  
      5.  The maximum height from a root node
  
          0
          |
          1   0
           \ /
            2
  
      Examples
      --------
      >>> from flash.core.serve.dag.task import get_deps
      >>> from flash.core.serve.dag.utils_test import add, inc
      >>> dsk = {'a1': 1, 'b1': (inc, 'a1'), 'b2': (inc, 'a1'), 'c1': (inc, 'b1')}
      >>> dependencies, dependents = get_deps(dsk)
      >>> _, total_dependencies = ndependencies(dependencies, dependents)
      >>> metrics = graph_metrics(dependencies, dependents, total_dependencies)
      >>> sorted(metrics.items())
      [('a1', (4, 2, 3, 1, 2)), ('b1', (2, 3, 3, 1, 1)), ('b2', (1, 2, 2, 0, 0)), ('c1', (1, 3, 3, 0, 0))]
  
      Returns
      -------
      metrics: Dict[key, Tuple[int, int, int, int, int]]
  
      """
      result = {}
      num_needed = {k: len(v) for k, v in dependents.items() if v}
      current = []
      current_pop = current.pop
      current_append = current.append
      for key, deps in dependents.items():
          if not deps:
              val = total_dependencies[key]
              result[key] = (1, val, val, 0, 0)
              for child in dependencies[key]:
                  num_needed[child] -= 1
                  if not num_needed[child]:
                      current_append(child)
  
      while current:
          key = current_pop()
          parents = dependents[key]
          if len(parents) == 1:
              (parent,) = parents
              (
                  total_dependents,
                  min_dependencies,
                  max_dependencies,
                  min_heights,
                  max_heights,
              ) = result[parent]
              result[key] = (
                  1 + total_dependents,
                  min_dependencies,
                  max_dependencies,
                  1 + min_heights,
                  1 + max_heights,
              )
          else:
              (
                  total_dependents,
                  min_dependencies,
                  max_dependencies,
                  min_heights,
                  max_heights,
              ) = zip(*(result[parent] for parent in dependents[key]))
              result[key] = (
                  1 + sum(total_dependents),
                  min(min_dependencies),
                  max(max_dependencies),
                  1 + min(min_heights),
                  1 + max(max_heights),
              )
          for child in dependencies[key]:
              num_needed[child] -= 1
              if not num_needed[child]:
                  current_append(child)
      return result
  
file_path: lightning-flash/src/flash/core/serve/dag/order.py
imports: from collections import defaultdict
  from math import log
  from flash.core.serve.dag.task import get_dependencies, getcycle, reverse_dict
  from flash.core.utilities.imports import _TOPIC_SERVE_AVAILABLE
label_desc: Use image node_id 2 for calling a global function with example usage: graph_metrics(dependencies, dependents, total_dependencies) and returns: result