class_docstr: Task graph composed of layers of dependent subgraphs
  
  This object encodes a Dask task graph that is composed of layers of
  dependent subgraphs, such as commonly occurs when building task graphs
  using high level collections like Dask array, bag, or dataframe.
  
  Typically each high level array, bag, or dataframe operation takes the task
  graphs of the input collections, merges them, and then adds one or more new
  layers of tasks for the new operation.  These layers typically have at
  least as many tasks as there are partitions or chunks in the collection.
  The HighLevelGraph object stores the subgraphs for each operation
  separately in sub-graphs, and also stores the dependency structure between
  them.
  
  Parameters
  ----------
  layers : Mapping[str, Mapping]
      The subgraph layers, keyed by a unique name
  dependencies : Mapping[str, set[str]]
      The set of layers on which each layer depends
  key_dependencies : dict[Key, set], optional
      Mapping (some) keys in the high level graph to their dependencies. If
      a key is missing, its dependencies will be calculated on-the-fly.
  
  Examples
  --------
  Here is an idealized example that shows the internal state of a
  HighLevelGraph
  
  >>> import dask.dataframe as dd
  
  >>> df = dd.read_csv('myfile.*.csv')  # doctest: +SKIP
  >>> df = df + 100  # doctest: +SKIP
  >>> df = df[df.name == 'Alice']  # doctest: +SKIP
  
  >>> graph = df.__dask_graph__()  # doctest: +SKIP
  >>> graph.layers  # doctest: +SKIP
  {
   'read-csv': {('read-csv', 0): (pandas.read_csv, 'myfile.0.csv'),
                ('read-csv', 1): (pandas.read_csv, 'myfile.1.csv'),
                ('read-csv', 2): (pandas.read_csv, 'myfile.2.csv'),
                ('read-csv', 3): (pandas.read_csv, 'myfile.3.csv')},
   'add': {('add', 0): (operator.add, ('read-csv', 0), 100),
           ('add', 1): (operator.add, ('read-csv', 1), 100),
           ('add', 2): (operator.add, ('read-csv', 2), 100),
           ('add', 3): (operator.add, ('read-csv', 3), 100)}
   'filter': {('filter', 0): (lambda part: part[part.name == 'Alice'], ('add', 0)),
              ('filter', 1): (lambda part: part[part.name == 'Alice'], ('add', 1)),
              ('filter', 2): (lambda part: part[part.name == 'Alice'], ('add', 2)),
              ('filter', 3): (lambda part: part[part.name == 'Alice'], ('add', 3))}
  }
  
  >>> graph.dependencies  # doctest: +SKIP
  {
   'read-csv': set(),
   'add': {'read-csv'},
   'filter': {'add'}
  }
  
  See Also
  --------
  HighLevelGraph.from_collections :
      typically used by developers to make new HighLevelGraphs
class_docstr_tok: ["Task","graph","composed","of","layers","of","dependent","subgraphs","This","object","encodes","a","Dask","task","graph","that","is","composed","of","layers","of","dependent","subgraphs",",","such","as","commonly","occurs","when","building","task","graphs","using","high","level","collections","like","Dask","array",",","bag",",","or","dataframe",".","Typically","each","high","level","array",",","bag",",","or","dataframe","operation","takes","the","task","graphs","of","the","input","collections",",","merges","them",",","and","then","adds","one","or","more","new","layers","of","tasks","for","the","new","operation",".","These","layers","typically","have","at","least","as","many","tasks","as","there","are","partitions","or","chunks","in","the","collection",".","The","HighLevelGraph","object","stores","the","subgraphs","for","each","operation","separately","in","sub-graphs",",","and","also","stores","the","dependency","structure","between","them",".","Parameters","--","--","--","--","--","layers",":","Mapping","[","str",",","Mapping","]","The","subgraph","layers",",","keyed","by","a","unique","name","dependencies",":","Mapping","[","str",",","set","[","str","]","]","The","set","of","layers","on","which","each","layer","depends","key_dependencies",":","dict","[","Key",",","set","]",",","optional","Mapping","(","some",")","keys","in","the","high","level","graph","to","their","dependencies",".","If","a","key","is","missing",",","its","dependencies","will","be","calculated","on-the-fly",".","Examples","--","--","--","--","Here","is","an","idealized","example","that","shows","the","internal","state","of","a","HighLevelGraph",">",">",">","import","dask.dataframe","as","dd",">",">",">","df","=","dd.read_csv","(","'myfile",".","*",".csv","'",")","#","doctest",":","+SKIP",">",">",">","df","=","df","+","100","#","doctest",":","+SKIP",">",">",">","df","=","df","[","df.name","==","'Alice","'","]","#","doctest",":","+SKIP",">",">",">","graph","=","df.__dask_graph__","(",")","#","doctest",":","+SKIP",">",">",">","graph.layers","#","doctest",":","+SKIP","{","'read-csv","'",":","{","(","'read-csv","'",",","0",")",":","(","pandas.read_csv",",","'myfile.0.csv","'",")",",","(","'read-csv","'",",","1",")",":","(","pandas.read_csv",",","'myfile.1.csv","'",")",",","(","'read-csv","'",",","2",")",":","(","pandas.read_csv",",","'myfile.2.csv","'",")",",","(","'read-csv","'",",","3",")",":","(","pandas.read_csv",",","'myfile.3.csv","'",")","}",",","'add","'",":","{","(","'add","'",",","0",")",":","(","operator.add",",","(","'read-csv","'",",","0",")",",","100",")",",","(","'add","'",",","1",")",":","(","operator.add",",","(","'read-csv","'",",","1",")",",","100",")",",","(","'add","'",",","2",")",":","(","operator.add",",","(","'read-csv","'",",","2",")",",","100",")",",","(","'add","'",",","3",")",":","(","operator.add",",","(","'read-csv","'",",","3",")",",","100",")","}","'filter","'",":","{","(","'filter","'",",","0",")",":","(","lambda","part",":","part","[","part.name","==","'Alice","'","]",",","(","'add","'",",","0",")",")",",","(","'filter","'",",","1",")",":","(","lambda","part",":","part","[","part.name","==","'Alice","'","]",",","(","'add","'",",","1",")",")",",","(","'filter","'",",","2",")",":","(","lambda","part",":","part","[","part.name","==","'Alice","'","]",",","(","'add","'",",","2",")",")",",","(","'filter","'",",","3",")",":","(","lambda","part",":","part","[","part.name","==","'Alice","'","]",",","(","'add","'",",","3",")",")","}","}",">",">",">","graph.dependencies","#","doctest",":","+SKIP","{","'read-csv","'",":","set","(",")",",","'add","'",":","{","'read-csv","'","}",",","'filter","'",":","{","'add","'","}","}","See","Also","--","--","--","--","HighLevelGraph.from_collections",":","typically","used","by","developers","to","make","new","HighLevelGraphs"]
docstr: Return new HighLevelGraph with only the tasks required to calculate keys.
  
  In other words, remove unnecessary tasks from dask.
  
  Parameters
  ----------
  keys
      iterable of keys or nested list of keys such as the output of
      ``__dask_keys__()``
  
  Returns
  -------
  hlg: HighLevelGraph
      Culled high level graph
code: def cull(self, keys: Iterable[Key]) -> HighLevelGraph:
      """Return new HighLevelGraph with only the tasks required to calculate keys.
  
      In other words, remove unnecessary tasks from dask.
  
      Parameters
      ----------
      keys
          iterable of keys or nested list of keys such as the output of
          ``__dask_keys__()``
  
      Returns
      -------
      hlg: HighLevelGraph
          Culled high level graph
      """
      from dask.layers import Blockwise
  
      keys_set = set(flatten(keys))
  
      all_ext_keys = self.get_all_external_keys()
      ret_layers: dict = {}
      ret_key_deps: dict = {}
      for layer_name in reversed(self._toposort_layers()):
          layer = self.layers[layer_name]
          # Let's cull the layer to produce its part of `keys`.
          # Note: use .intersection rather than & because the RHS is
          # a collections.abc.Set rather than a real set, and using &
          # would take time proportional to the size of the LHS, which
          # if there is no culling can be much bigger than the RHS.
          output_keys = keys_set.intersection(layer.get_output_keys())
          if output_keys:
              culled_layer, culled_deps = layer.cull(
                  output_keys, all_ext_keys
              )
              # Update `keys` with all layer's external key dependencies, which
              # are all the layer's dependencies (`culled_deps`) excluding
              # the layer's output keys.
              external_deps = set()
              for d in culled_deps.values():
                  external_deps |= d
              external_deps -= culled_layer.get_output_keys()
              keys_set |= external_deps
  
              # Save the culled layer and its key dependencies
              ret_layers[layer_name] = culled_layer
              if (
                  isinstance(layer, Blockwise)
                  or isinstance(layer, MaterializedLayer)
                  or (
                      layer.is_materialized()
                      and (len(layer) == len(culled_deps))
                  )
              ):
                  # Don't use culled_deps to update ret_key_deps
                  # unless they are "direct" key dependencies.
                  #
                  # Note that `MaterializedLayer` is "safe", because
                  # its `cull` method will return a complete dict of
                  # direct dependencies for all keys in its subgraph.
                  # See: https://github.com/dask/dask/issues/9389
                  # for performance motivation
                  ret_key_deps.update(culled_deps)
  
      # Converting dict_keys to a real set lets Python optimise the set
      # intersection to iterate over the smaller of the two sets.
      ret_layers_keys = set(ret_layers.keys())
      ret_dependencies = {
          layer_name: self.dependencies[layer_name] & ret_layers_keys
          for layer_name in ret_layers
      }
  
      return HighLevelGraph(ret_layers, ret_dependencies, ret_key_deps)
  
imports: from __future__ import annotations
  import abc
  import copy
  import html
  from collections.abc import Collection, Hashable, ItemsView, Iterable, Iterator, KeysView, Mapping, Sequence, Set, ValuesView
  from typing import Any
  import tlz
  import dask
  from dask import config
  from dask.base import clone_key, flatten, is_dask_collection
  from dask.core import keys_in_tasks, reverse_dict
  from dask.typing import DaskCollection, Graph, Key
  from dask.utils import ensure_dict, import_required, key_split
  from dask.widgets import get_template
label_desc: Use image node_id 18 for calling the HighLevelGraph obj's underlying member method code with example usage: obj.cull(keys) and returns: HighLevelGraph