next up previous index
Up: Recursion Previous: Recursion   Index

Less Abstract Version

The same function is shown below, in an ugglier, but more precise manner. It has been expressed solely using elements of the Q ISA1, and all intermediate values have been declared.

uint32 udiv32( uint32, uint32 );
uint32 uadd32( uint32, uint32 );

Output = log2( Input );     //  Task A
log2( x ) = y
  where
    uint32  y;
    uint32  i;
    uint32  j;
    uint32  k;
    uint32  one = 1;
    uint32  two = 2;

    i = udiv32( x, two );
    j = log2( i );          //  Task B
    k = uadd32( j, one );
    y = if (x > 1) then k else 0 fi;
  end;

When this program fragment is expanded, the log2 graph will be instantiated once to handle two different invocations: Once for the application labeled task A, and once for task B (the internal recursion). Conditional operators are inserted on the input and output streams, to select them properly for position 0 along dimension r (task A), and all other positions along r (task B). In order to identify the unique state associated with each level of recursion, the r dimension is added to the streams in the expanded log2 graph. The resulting ``flattened'' code, assuming one dimensional Input and Output streams, is shown below.

dimension d,r;
uint32 Input.d;
uint32 Output.d;
uint32 x.d,r;
uint32 y.d,r;
uint32 i.d,r;
uint32 j.d,r;
uint32 k.d,r;
uint32 h.d,r;
uint32 one = 1;
uint32 two = 2;
uint32 udiv32( uint32, uint32 );
uint32 uadd32( uint32, uint32 );

Output = select.r( y, 0, 1, 1 );   // y @.r 0
x = if (#.d == 0) then Input  else h  fi;
h = resample.r( i, 1, -1 );       // prev.r i
i = udiv32( x, two );
j = resample.r( y, 1, 1 );        // next.r y
k = uadd32( j, one );
y = if (x > 1) then k  else 0  fi;



Footnotes

... ISA1
With the exception that mcond operators with one or two elements are shown as if expressions, in order to greatly improve readability.


magiceight-web@media.mit.edu