18 |
structure DstOp = DstIL.Op |
structure DstOp = DstIL.Op |
19 |
structure VMap = SrcIL.Var.Map |
structure VMap = SrcIL.Var.Map |
20 |
|
|
21 |
|
(* a tree representation of nested iterations over the image space, where the |
22 |
|
* height of the tree corresponds to the number of dimensions and at each node |
23 |
|
* we have as many children as there are iterations. |
24 |
|
*) |
25 |
|
structure IT = |
26 |
|
struct |
27 |
|
datatype ('nd, 'lf) iter_tree |
28 |
|
= LF of 'lf |
29 |
|
| ND of ('nd * ('nd, 'lf) iter_tree list) |
30 |
|
|
31 |
|
fun create (depth, width, ndAttr, f, lfAttr, init) = let |
32 |
|
fun mk (d, i, arg) = if (d < depth) |
33 |
|
then ND(ndAttr arg, List.tabulate(width, fn j => mk(d+1, j, f(j, arg)))) |
34 |
|
else LF(lfAttr arg) |
35 |
|
in |
36 |
|
mk (0, 0, init) |
37 |
|
end |
38 |
|
|
39 |
|
fun map (nd, lf) t = let |
40 |
|
fun mapf (LF x) = LF(lf x) |
41 |
|
| mapf (ND(i, kids)) = ND(nd i, List.map mapf kids) |
42 |
|
in |
43 |
|
mapf t |
44 |
|
end |
45 |
|
|
46 |
|
fun foldr f init t = let |
47 |
|
fun fold (LF x, acc) = f(x, acc) |
48 |
|
| fold (ND(_, kids), acc) = List.foldr fold acc kids |
49 |
|
in |
50 |
|
fold t |
51 |
|
end |
52 |
|
|
53 |
|
end |
54 |
|
|
55 |
(* expand the field Inside operator into a image-space test *) |
(* expand the field Inside operator into a image-space test *) |
56 |
fun expandInside (env, result, pos, fld) = let |
fun expandInside (env, result, pos, fld) = let |
57 |
val pos' = lookupVar (env, pos) |
val pos' = lookupVar (env, pos) |
79 |
DstIL.Var.new (prefix ^ Vector.sub(dimNames, d)) |
DstIL.Var.new (prefix ^ Vector.sub(dimNames, d)) |
80 |
|
|
81 |
fun assign (x, rator, args) = (x, DstIL.OP(rator, args)) |
fun assign (x, rator, args) = (x, DstIL.OP(rator, args)) |
82 |
|
fun cons (x, args) = (x, DstIL.CONS args) |
83 |
fun intLit (x, i) = (x, DstIL.LIT(Literal.Int(IntInf.fromInt i))) |
fun intLit (x, i) = (x, DstIL.LIT(Literal.Int(IntInf.fromInt i))) |
84 |
|
|
85 |
fun generate (n, f) = List.concat(List.tabulate(n, f)) |
fun generate (n, f) = List.concat(List.tabulate(n, f)) |
102 |
assign(n, DstOp.TruncToInt dim, [nd]) |
assign(n, DstOp.TruncToInt dim, [nd]) |
103 |
] |
] |
104 |
(* generate code to load the voxel data *) |
(* generate code to load the voxel data *) |
105 |
fun forAxis (axis, suffix, offsets) = if (axis > 0) |
val voxIter = let |
106 |
then generate (2*s, fn i => let |
fun f (i, (offsets, id)) = (i - (s - 1) :: offsets, i::id) |
107 |
val suffix = suffix ^ Int.toString i |
fun g (offsets, id) = { |
108 |
val offsets = i - (s - 1) :: offsets |
offsets = offsets, |
109 |
in |
vox = DstIL.Var.new(String.concat("v" :: List.map Int.toString id)) |
110 |
forAxis (axis-1, suffix, offsets) |
} |
111 |
end) |
in |
112 |
else let |
IT.create (depth, width, fn _ => (), f, g, ([], [])) |
113 |
|
end |
114 |
|
val loadCode = let |
115 |
|
fun genCode ({offsets, vox}, code) = let |
116 |
fun computeIndices (_, []) = ([], []) |
fun computeIndices (_, []) = ([], []) |
117 |
| computeIndices (i, offset::offsets) = let |
| computeIndices (i, offset::offsets) = let |
118 |
val index = newVar_dim("i", i) |
val index = newVar_dim("i", i) |
119 |
val t1 = newVar "t1" |
val t1 = newVar "t1" |
120 |
val t2 = newVar "t2" |
val t2 = newVar "t2" |
121 |
val (indices, code) = computeIndices (i+1, offsets) |
val (indices, code) = computeIndices (i+1, offsets) |
122 |
val code = intLit(t1, offset) :: |
val code = |
123 |
|
intLit(t1, offset) :: |
124 |
assign(t2, DstOp.Select i, [n]) :: |
assign(t2, DstOp.Select i, [n]) :: |
125 |
assign(index, DstOp.Add(DstOp.IntTy), [t1, t2]) :: |
assign(index, DstOp.Add(DstOp.IntTy), [t1, t2]) :: |
126 |
code |
code |
130 |
end |
end |
131 |
val (indices, indicesCode) = computeIndices (0, ~(s-1) :: offsets) |
val (indices, indicesCode) = computeIndices (0, ~(s-1) :: offsets) |
132 |
val a = DstIL.Var.new "a" |
val a = DstIL.Var.new "a" |
|
val vox = DstIL.Var.new("v" ^ suffix) |
|
133 |
in |
in |
134 |
indicesCode :: [ |
indicesCode :: [ |
135 |
assign(a, VoxelAddress v, indices), |
assign(a, VoxelAddress v, indices), |
136 |
assign(vox, LoadVoxels(ty, 2*s)) |
assign(vox, LoadVoxels(ty, 2*s)) |
137 |
] |
] @ code |
138 |
|
end |
139 |
|
in |
140 |
|
IT.foldr genCode [] voxIter |
141 |
|
end |
142 |
|
val voxVars = IT.foldr (fn ({vox, ...}, vs) => vox::vs) [] voxIter |
143 |
|
(* generate the code for computing the convolution coefficients *) |
144 |
|
(* SOMETHING *) |
145 |
|
(* generate the reduction code *) |
146 |
|
fun genReduce (d, IT.ND(kids), code) = |
147 |
|
if (d < dim) |
148 |
|
then List.foldr (fn (nd, code) => genReduce(d+1, nd, code)) code kids |
149 |
|
else let (* the kids will all be leaves *) |
150 |
|
val vv = newVar "vv" |
151 |
|
fun getVox (IT.LF{vox, offsets}) = vox |
152 |
|
in |
153 |
|
cons (vv, List.map getVox kids) :: |
154 |
|
assign (t, DstIL.Dot, [h, vv]) :: code |
155 |
end |
end |
156 |
(* FIXME: we need a way to get out the voxel-vector variables too! *) |
val reduceCode = genReduce (1, voxIter, []) |
|
val loadCode = forAxis (dim-1, "", []) |
|
157 |
in |
in |
158 |
?? |
transformCode @ loadCode @ reduceCode |
159 |
end |
end |
160 |
|
|
161 |
end |
end |