emacs.d/clones/www.cs.cmu.edu/Groups/AI/html/cltl/clm/node358.html

176 lines
10 KiB
HTML
Raw Normal View History

2022-08-26 19:11:35 +02:00
<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
<!Converted with LaTeX2HTML 0.6.5 (Tue Nov 15 1994) by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds >
<HEAD>
<TITLE>A.3.2. Constraint Cycles</TITLE>
</HEAD>
<BODY>
<meta name="description" value=" Constraint Cycles">
<meta name="keywords" value="clm">
<meta name="resource-type" value="document">
<meta name="distribution" value="global">
<P>
<b>Common Lisp the Language, 2nd Edition</b>
<BR> <HR><A NAME=tex2html6178 HREF="node359.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html6176 HREF="node356.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html6170 HREF="node357.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html6180 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html6181 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
<B> Next:</B> <A NAME=tex2html6179 HREF="node359.html"> Defining New Series </A>
<B>Up:</B> <A NAME=tex2html6177 HREF="node356.html"> Optimization</A>
<B> Previous:</B> <A NAME=tex2html6171 HREF="node357.html"> Basic Restrictions</A>
<HR> <P>
<H2><A NAME=SECTION003432000000000000000>A.3.2. Constraint Cycles</A></H2>
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
Even if a series expression satisfies all of the restrictions above, it
still may not be possible to transform the expression into a loop. The
sole remaining problem is that if a series is used in two places, the
two uses may place incompatible constraints on the times at which series
elements should be produced.
<P>
The series expression below shows a situation where this problem arises.
The expression creates a series <tt>x</tt> of the elements in a list. It then
creates a normalized series by dividing each element of <tt>x</tt> by the sum
of the elements in <tt>x</tt>. Finally, the expression returns the maximum of
the normalized elements.
<P><pre>
(let ((x (scan '(1 2 5 2)))) ;Warning message issued
(collect-max (#M/ x (series (collect-sum x))))) => 1/2
</pre><P>
<P>
The two uses of <tt>x</tt> in the expression place contradictory
constraints on the way pipelined evaluation must proceed; <tt>collect-sum</tt>
requires that all of the elements of <tt>x</tt> be produced before the sum can
be returned, and <tt>series</tt> requires that its input be available before it
can start to produce its output. However, <tt>#M/</tt> requires that the
first element of <tt>x</tt> be available at the same time as the first element
of the output of <tt>series</tt>. For pipelining to work,
the first element of the output of <tt>series</tt> (and therefore the output
of <tt>collect-sum</tt>) must be available before the second element of
<tt>x</tt> is produced. Unfortunately, this is impossible.
<P>
The essence of the inconsistency above is the cycle of constraints used in
the argument. This in turn stems from a cycle in the data flow graph
underlying the expression. In
figure <A HREF="node358.html#SERIESF1FIGURE">A-1</A> function calls are represented by boxes and data
flow is represented by arrows. Simple arrows indicate the flow of series
values and cross-hatched arrows indicate the flow of non-series values.
<P>
<A NAME=SERIESF1FIGURE>&#160;</A>
<listing>
----------------------------------------------------------------
Figure A-1: A Constraint Cycle in a Series Expression
+------+ +-----+ +-----+
-->| scan |----------------------------------->| #M/ |-->| max |-->
+------+ \ +-----+ +--------+ / +-----+ +-----+
-->| sum |-++++->| series |--
+-----+ +--------+
----------------------------------------------------------------
</listing>
<P>
Given a data flow graph corresponding to a series expression, a <i>constraint cycle</i> is a closed oriented loop of data flow arcs such
that each arc is traversed exactly once and no non-series arc
is traversed backward. (Series data flow arcs can be traversed in either
direction.) A constraint cycle is said to <i>pass through</i> an input or
output port when exactly one of the arcs in the cycle touches the port. In
figure <A HREF="node358.html#SERIESF1FIGURE">A-1</A> the data flow arcs touching <tt>scan</tt>, <tt>sum</tt>,
<tt>series</tt>, and <tt>#M/</tt> form a constraint cycle. Note that if the
output of <tt>scan</tt> were not a series, this loop would not be a constraint
cycle, because there would be no valid way to traverse it. Also note that
while the constraint cycle passes through all the other ports it touches,
it does not pass through the output of <tt>scan</tt>.
<P>
Whenever a constraint cycle passes through a non-series output, an argument
analogous to the one above can be constructed and therefore pipelining will be
impossible. When this situation arises, a warning message is issued
identifying the problematical port and the cycle passing through it. For
instance, the warning triggered by the example above states that the
constraint cycle associated with <tt>scan</tt>, <tt>collect-sum</tt>,
<tt>series</tt>, and <tt>#M/</tt> passes through the non-series output of
<tt>collect-sum</tt>.
<P>
Given this kind of detailed information, it is easy to alleviate the
problem. To start with, every cycle must contain at least one function
that has two series data flows leaving it. At worst, the cycle can be broken by
duplicating this function (and any functions computing series used by it).
For instance, the example above can be
rewritten as shown below.
<P><pre>
(let ((x (scan '(1 2 5 2)))
(sum (collect-sum (scan '(1 2 5 2)))))
(collect-max (#M/ x (series sum))))
=> 1/2
</pre><P>
<P>
It would be easy enough to automatically apply code copying to break
problematical constraint cycles. However, this is not done for two
reasons. First, there is considerable virtue in maintaining the property
that each function in a series expression turns into one piece of
computation in the loop produced. Users can be confident that series
expressions that look simple and efficient actually are simple and
efficient. Second, with a little creativity, constraint problems can often
be resolved in ways that are much more efficient than copying code. In the
example above, the conflict can be eliminated efficiently by interchanging
the operation of computing the maximum with the operation of normalizing an
element.
<P><pre>
(let ((x (scan '(1 2 5 2))))
(/ (collect-max x) (collect-sum x))) => 1/2
</pre><P>
<P>
The restriction that optimizable series expressions cannot contain
constraint cycles that pass through non-series outputs places limitations on
the qualitative character of optimizable series expressions. In particular,
they all must have the general form of creating some number of series using
scanners, computing various intermediate series using transducers, and then
computing one or more summary results using collectors. The output of a
collector cannot be used in the intermediate computation unless it is the
output of a separate subexpression.
<P>
It is worthy of note that the last expression above fixes the constraint
conflict by moving the non-series output out of the cycle, rather than by
breaking the cycle. This illustrates the fact that constraint cycles that
do not pass through non-series outputs do not necessarily cause problems.
They cause problems only if they pass through <i>off-line</i> ports.
<P>
A series input port or series output port of a series function is <i>on-line</i>
if and only if it is processed in lockstep with all the other on-line
ports as follows: the initial element of each on-line input is
read, then the initial element of each on-line output is written, then the
second element of each on-line input is read, then the second element of
each on-line output is written, and so on. Ports that are not on-line are
off-line. If all of the series ports of a function are on-line, the
function is said to be on-line; otherwise, it is off-line. (The above
extends the standard definition of the term <i>on-line</i> so that it applies
to individual ports as well as whole functions.)
<P>
If all of the ports a cycle passes through are on-line, the lockstep
processing of these ports guarantees that there cannot be any conflicts
between the constraints associated with the cycle. However, passing
through an off-line port leads to the same kinds of problems as passing
through a non-series output.
<P>
Most of the series functions are on-line. In particular, scanners and
collectors are all on-line as are many transducers. However, the
transducers in section <A HREF="node353.html#SERIESOLSECTION">A.2.4</A> are off-line. In particular, the
series inputs of <tt>catenate</tt>, <tt>choose-if</tt>, <tt>chunk</tt>, <tt>expand</tt>, <tt>mask</tt>,
<tt>mingle</tt>, <tt>positions</tt>, and <tt>subseries</tt> along with the
series outputs of <tt>choose</tt>, <tt>split</tt>, and <tt>split-if</tt> are off-line.
<P>
In summary, the fourth and final restriction is that <b>for optimization
to be possible, a series expression cannot contain a constraint cycle that
passes through a non-series output or an off-line port</b>. Whenever this
restriction is violated a warning message is issued. Violations can be
fixed either by breaking the cycle or restructuring the computation so that
the offending port is removed from the cycle.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR> <HR><A NAME=tex2html6178 HREF="node359.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html6176 HREF="node356.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html6170 HREF="node357.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html6180 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html6181 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
<B> Next:</B> <A NAME=tex2html6179 HREF="node359.html"> Defining New Series </A>
<B>Up:</B> <A NAME=tex2html6177 HREF="node356.html"> Optimization</A>
<B> Previous:</B> <A NAME=tex2html6171 HREF="node357.html"> Basic Restrictions</A>
<HR> <P>
<HR>
<P><ADDRESS>
AI.Repository@cs.cmu.edu
</ADDRESS>
</BODY>