19.11.2014 Views

The Fortress Language Specification - CiteSeerX

The Fortress Language Specification - CiteSeerX

The Fortress Language Specification - CiteSeerX

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

(r 1 , r 2 , . . .r n ) ⊕= T (T 1 , T 2 , . . .T n ), ⊕[gs] (do<br />

(r 1 , r 2 , . . .r n ) : (T 1 , T 2 , . . .T n ) := Identity⊕<br />

block<br />

(r 1 , r 2 , . . .r n )<br />

end)<br />

In practice, a tuple type is not a monoid. If there is only one reduction variable, this is not a problem. If there are no<br />

reduction variables, we simply use the type NoReduction used in desugaring assignments. When there are multiple<br />

reduction variables, we use nested applications of types extending the trait ReductionPair. <strong>The</strong>se types encode<br />

the common properties of the variables being reduced. Recall that every reduction variable must at least have type<br />

Monoid, so it is not difficult to guarantee that ReductionPair itself also extends Monoid.<br />

32.8.2 Accounting for Dependencies among Generators<br />

<strong>The</strong> naive desugaring for generator lists in Figure 32.1 assumes there are always data dependencies among generators.<br />

<strong>The</strong> actual desugaring makes use of the join method in the Generator trait to group together generators that have<br />

no data dependencies. <strong>The</strong> goal is to permit library code to define more efficient merged generators for generator<br />

pairs. For example, it is possible for the join method to take the generator list i ← 1 #100, j ← 2 #200 and generate<br />

a blocked two-dimensional traversal. This could then be joined with k ← 3 #300 to obtain a three-dimensional<br />

blocked traversal.<br />

However, most generators will simply make use of the default definition of join which calls SimplePairGenerator:<br />

object SimplePairGenerator A, B (outer : Generator A ,inner : Generator B )<br />

extends Generator (A, B) <br />

size : Z64 = outer.size · inner.size<br />

generate R extends Monoid R, ⊕ ,opr ⊕ (body : (A, B) → R) :R =<br />

outer.generate(fn (a : A) ⇒ inner.generate(fn (b : B) ⇒ body(a, b)))<br />

join N (other : Generator N ) : Generator ((A, B), N) =<br />

SimpleMapGenerator(outer.join(inner.join(other)),<br />

(fn (a, (b, n)) ⇒ ((a, b), n)))<br />

end<br />

Note how SimplePairGenerator itself overrides the join method. When we attempt to join an existing pair of joined<br />

generators, we first attempt to join the inner generator of the pair with the other generator (the new innermost<br />

generator) passed in. This means that every generator will have the opportunity to combine with both its left and right<br />

neighbors if neither has a dependency which prevents it. Note that we use a SimpleMapGenerator, which simply<br />

applies a function to the result of another generator, to re-nest the tuples produced by the nested join operation.<br />

Which pairs of adjacent traversals are combined using join ? This question is complicated by examples such as<br />

i ← 1 : 100, j ← 1 : 100, k ← i : 100, l ← j :100 . We can either combine i and j traversals, or we can combine j<br />

and k traversals. In the former case we can also combine k and l traversals. <strong>The</strong> <strong>Fortress</strong> compiler is free to choose<br />

any grouping subject to the following constraints:<br />

• Two generators may not be combined using join if the second is data dependent upon the first.<br />

• Generator order must be preserved when invoking join .<br />

• When a chain of three or more generators is joined, the traversals must be combined left-associatively.<br />

We can obtain a simple greedy desugaring which joins together traversals in accordance with the above rules by simply<br />

adding the following desugaring rule which takes precedence over those given in Figure 32.1 when each variable bound<br />

in v 1 does not occur free in g 2 .<br />

T R, ⊞[ v 1 ← g 1 , v 2 ← g 2 ,gs ] body = T R, ⊞[ (v 1 , v 2 ) ← g 1 .join(g 2 ),gs ] body<br />

224

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!