anchor.diff:  ;;;
   ;;; 2. By construction, the nodes starting from one critical node, up to
   ;;;    and including the next critical nodes, form a tree of application,
  -;;;    reduction, reference and fusion nodes. To eliminate fusion nodes in
  -;;;    the later stages, determine a set of index spaces such that their
  -;;;    union is the index space of the current critical node, but such that
  -;;;    each index space lies uniquely within a particular input of each
  -;;;    fusion node.
  -;;;
  -;;; 3. Each particular index space from 2. denotes a fusion-free
  -;;;    sub-problem on the way to computing the current critical
  -;;;    node. Determine the iteration space of this sub-problem and the set
  -;;;    of referenced immediates.
  -;;;
  -;;; 4. Given the iteration space and the set of referenced immediates,
  -;;;    translate the tree into an explicit blueprint. The blueprint
  -;;;    describes how the given inputs are used to compute the target. It is
  -;;;    important that this blueprint is normalized, such that as many
  -;;;    computationally similar operations as possible have the same
  -;;;    blueprint. To achieve this, blueprints do not use index space
  -;;;    coordinates, but the storage coordinates of the source and target
  -;;;    immediates.
  +;;;    reduction, reference and fusion nodes. To eliminate all fusion
  +;;;    nodes, determine a set of index spaces such that their union is the
  +;;;    index space of the current critical node, but such that each index
  +;;;    space lies only within a single input of each fusion node.
  +;;;
  +;;; 3. Each particular index space from the previous step denotes a
  +;;;    fusion-free subtask in the process of computing the values of a
  +;;;    critical node. Determine the iteration space of this subtask and the
  +;;;    set of referenced immediates, called sources.
  +;;;
  +;;; 4. Given the iteration space and the set of sources, translate the tree
  +;;;    into an explicit blueprint. The blueprint describes how target
  +;;;    values can be computed from the given source. It is important that
  +;;;    this blueprint is normalized, such that as many computationally
  +;;;    similar operations as possible have the same blueprint. To achieve
  +;;;    this, blueprints do not use index space coordinates, but the storage
  +;;;    coordinates of the source and target immediates.
   ;;;
   ;;; 5. Use each blueprint, together with the set of sources, the target and
  -;;;    the iteration space, to create one kernel and associates its target
  -;;;    node. Once every critical node and index space thereof has been
  -;;;    processed, the algorithm terminates.
  +;;;    the iteration space, to create one kernel. Attach this kernel to its
  +;;;    target immediate.
  +;;;
  +;;; Once every critical node and index space thereof has been processed,
  +;;; the algorithm terminates.
   
   (defun kernelize (graph-roots)
     (kernelize-subtrees
  
positive.code: ;;;   broadcasting reference is usually orders of magnitude smaller than
  ;;;   the output, so allocating it explicitly is hardly severe.
  ;;;
  ;;; - A node is a critical node, if it has more than one input that
  ;;;   contains --- possibly further upward, but below the next critical
  ;;;   node --- a reduction node. This rather arcane criterion achieves,
  ;;;   that the iteration space of each kernel is an n-dimensional strided
  ;;;   cube, simplifying later analysis considerably. Introducing these
  ;;;   critical nodes is not terribly expensive, since the target of some
  ;;;   reductions is usually orders of magnitude smaller than their inputs.
  ;;;
  ;;; The first step in the algorithm is the creation of a *USE-TABLE*, a
  ;;; hash table mapping each graph node to its successors. It would seem
  ;;; more efficient to track the users of each node at DAG construction time
  ;;; and avoid this indirection, but we are only interested in those users
  ;;; that are reachable via the given graph roots. This way the system
  ;;; implicitly eliminates dead code.
  ;;;
  ;;; Once the *USE-TABLE* is populated, the graph is traversed a second
  ;;; time, to generate a kernelized copy of it. A node with more than one
  ;;; user triggers the creation of a new intermediate result and one or more
  ;;; kernels. The hash table *KERNEL-TABLE* memoizes repeated calls to
  ;;; KERNELIZE-NODE.
  
  (defun kernelize-subtrees (subtree-fn graph-roots)
    "Invoke SUBTREE-FN on each subtree in the graph spanned by the supplied
  
negative.code: ;;;
  ;;; The goal is to translate a data flow graph into a graph of executable
  ;;; parts, called kernels. The data flow nodes form a DAG (directed acyclic
  ;;; graph). The data flow graph is fully determined by a set of graph
  ;;; roots, typically the nodes passed to SCHEDULE.
  ;;;
  ;;; The resulting graph consists only of immediate values. Each immediate
  ;;; hash a possibly empty set of kernels. Each kernel describes how values
  ;;; of a subspace of the index space of its target immediate can be
  ;;; computed. Furthermore each kernel tracks the set of its sources,
  ;;; i.e. those immediates that are referenced during their
  ;;; evaluation. Since the resulting immediate graph is used to decide a
  ;;; scheduling and allocation strategy, it is important that its kernels
  ;;; are easy to analyze, yet expressive enough to denote fast programs.
  