1 : |
jhr |
280 |
(* high-to-mid.sml
|
2 : |
|
|
*
|
3 : |
|
|
* COPYRIGHT (c) 2010 The Diderot Project (http://diderot.cs.uchicago.edu)
|
4 : |
|
|
* All rights reserved.
|
5 : |
|
|
*
|
6 : |
|
|
* Translation from HighIL to MidIL representations.
|
7 : |
|
|
*)
|
8 : |
|
|
|
9 : |
|
|
structure HighToMid : sig
|
10 : |
|
|
|
11 : |
|
|
val translate : HighIL.program -> MidIL.program
|
12 : |
|
|
|
13 : |
|
|
end = struct
|
14 : |
|
|
|
15 : |
|
|
structure SrcIL = HighIL
|
16 : |
|
|
structure SrcOp = SrcIL.Op
|
17 : |
|
|
structure DstIL = MidIL
|
18 : |
|
|
structure DstOp = DstIL.Op
|
19 : |
|
|
structure VMap = SrcIL.Var.Map
|
20 : |
|
|
|
21 : |
|
|
(* expand the field Inside operator into a image-space test *)
|
22 : |
|
|
fun expandInside (env, result, pos, fld) = let
|
23 : |
|
|
val pos' = lookupVar (env, pos)
|
24 : |
|
|
val fld = (case valueOf fld
|
25 : |
|
|
of SrcIL.OP(SrcOp.Field fld, []) => fld
|
26 : |
|
|
| _ => raise Fail "bogus field binding"
|
27 : |
|
|
(* end case *))
|
28 : |
|
|
fun expand (FieldDef.CONV(_, img, _)) => let
|
29 : |
|
|
val imgPos = newVar ??
|
30 : |
|
|
in [
|
31 : |
|
|
(imgPos, DstIL.OP(DstOp.Transform img, [pos'])),
|
32 : |
|
|
(result, DstIL.OP(DstOp.Inside img, [imgPos]))
|
33 : |
|
|
] end
|
34 : |
|
|
| expand (FieldDef.NEG fld) => expand fld
|
35 : |
|
|
| expand (FieldDef.SUM(fld1, dlf2)) => raise Fail "expandInside: SUM"
|
36 : |
|
|
in
|
37 : |
|
|
expand fld
|
38 : |
|
|
end
|
39 : |
|
|
|
40 : |
jhr |
314 |
(* generate a new variable indexed by dimension *)
|
41 : |
|
|
local
|
42 : |
|
|
val dimNames = Vector.fromList[ "x", "y", "z" ];
|
43 : |
|
|
in
|
44 : |
|
|
fun newVar_dim (prefix, d) =
|
45 : |
|
|
DstIL.Var.new (prefix ^ Vector.sub(dimNames, d))
|
46 : |
|
|
|
47 : |
|
|
fun assign (x, rator, args) = (x, DstIL.OP(rator, args))
|
48 : |
|
|
fun intLit (x, i) = (x, DstIL.LIT(Literal.Int(IntInf.fromInt i)))
|
49 : |
|
|
|
50 : |
|
|
fun generate (n, f) = List.concat(List.tabulate(n, f))
|
51 : |
|
|
|
52 : |
|
|
(* generate code for probing the field (D^k (v * h)) at pos *)
|
53 : |
|
|
fun probe (result, (k, v, h), pos) = let
|
54 : |
|
|
val ImageInfo.ImgInfo{dim, ty=([], ty), ...} = v
|
55 : |
|
|
val dimTy = DstOp.VecTy dim
|
56 : |
|
|
val s = Kernel.support h
|
57 : |
|
|
val sTy = DstOp.VecTy(2*s)
|
58 : |
|
|
(* generate the transform code *)
|
59 : |
|
|
val x = DstIL.Var.new "x" (* image-space position *)
|
60 : |
|
|
val f = DstIL.Var.new "f"
|
61 : |
|
|
val nd = DstIL.Var.new "nd"
|
62 : |
|
|
val n = DstIL.Var.new "n"
|
63 : |
|
|
val transformCode = [
|
64 : |
|
|
assign(x, DstIL.Transform v, [pos]),
|
65 : |
|
|
assign(nd, DstIL.Floor dim, [x]),
|
66 : |
|
|
assign(f, DstIL.Sub dimTy, [x, nd]),
|
67 : |
|
|
assign(n, DstOp.TruncToInt dim, [nd])
|
68 : |
|
|
]
|
69 : |
|
|
(* generate code to load the voxel data *)
|
70 : |
|
|
fun forAxis (axis, suffix, offsets) = if (axis > 0)
|
71 : |
|
|
then generate (2*s, fn i => let
|
72 : |
|
|
val suffix = suffix ^ Int.toString i
|
73 : |
|
|
val offsets = i - (s - 1) :: offsets
|
74 : |
|
|
in
|
75 : |
|
|
forAxis (axis-1, suffix, offsets)
|
76 : |
|
|
end)
|
77 : |
|
|
else let
|
78 : |
|
|
fun computeIndices (_, []) = ([], [])
|
79 : |
|
|
| computeIndices (i, offset::offsets) = let
|
80 : |
|
|
val index = newVar_dim("i", i)
|
81 : |
|
|
val t1 = newVar "t1"
|
82 : |
|
|
val t2 = newVar "t2"
|
83 : |
|
|
val (indices, code) = computeIndices (i+1, offsets)
|
84 : |
|
|
val code = intLit(t1, offset) ::
|
85 : |
|
|
assign(t2, DstOp.Select i, [n]) ::
|
86 : |
|
|
assign(index, DstOp.Add(DstOp.IntTy), [t1, t2]) ::
|
87 : |
|
|
code
|
88 : |
|
|
val indices = index::indices
|
89 : |
|
|
in
|
90 : |
|
|
(indices, code)
|
91 : |
|
|
end
|
92 : |
|
|
val (indices, indicesCode) = computeIndices (0, ~(s-1) :: offsets)
|
93 : |
|
|
val a = DstIL.Var.new "a"
|
94 : |
|
|
val vox = DstIL.Var.new("v" ^ suffix)
|
95 : |
|
|
in
|
96 : |
|
|
indicesCode :: [
|
97 : |
|
|
assign(a, VoxelAddress v, indices),
|
98 : |
|
|
assign(vox, LoadVoxels(ty, 2*s))
|
99 : |
|
|
]
|
100 : |
|
|
end
|
101 : |
|
|
(* FIXME: we need a way to get out the voxel-vector variables too! *)
|
102 : |
|
|
val loadCode = forAxis (dim-1, "", [])
|
103 : |
|
|
in
|
104 : |
|
|
??
|
105 : |
|
|
end
|
106 : |
|
|
|
107 : |
|
|
end
|
108 : |
|
|
|
109 : |
jhr |
280 |
fun expandProbe (env, result, fld, pos) = let
|
110 : |
|
|
val pos' = lookupVar (env, pos)
|
111 : |
|
|
val fld = (case valueOf fld
|
112 : |
|
|
of SrcIL.OP(SrcOp.Field fld, []) => fld
|
113 : |
|
|
| _ => raise Fail "bogus field binding"
|
114 : |
|
|
(* end case *))
|
115 : |
|
|
fun expand (result, FieldDef.CONV(0, img, h)) => let
|
116 : |
|
|
val imgPos = newVar ??
|
117 : |
|
|
val xformStm = (imgPos, DstIL.OP(DstOp.Transform img, [pos']))
|
118 : |
|
|
(* generate samples based on kernel support and dimensionality of image *)
|
119 : |
|
|
in
|
120 : |
|
|
xformStm :: probeStms
|
121 : |
|
|
end
|
122 : |
|
|
| expand (FieldDef.CONV(k, img, h)) => ??
|
123 : |
|
|
| expand (FieldDef.NEG fld) => let
|
124 : |
|
|
val r = newVar ??
|
125 : |
|
|
val stms = expand (r, fld)
|
126 : |
|
|
in
|
127 : |
|
|
(r, DstIL.OP(DstOp.Neg ty, [r])) :: stms
|
128 : |
|
|
end
|
129 : |
|
|
| expand (FieldDef.SUM(fld1, dlf2)) => raise Fail "expandInside: SUM"
|
130 : |
|
|
in
|
131 : |
|
|
List.rev (expand (result, fld))
|
132 : |
|
|
end
|
133 : |
|
|
|
134 : |
|
|
end
|