Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] Diff of /trunk/src/compiler/high-to-mid/probe.sml
ViewVC logotype

Diff of /trunk/src/compiler/high-to-mid/probe.sml

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1115, Thu May 5 04:42:18 2011 UTC revision 1116, Thu May 5 04:49:02 2011 UTC
# Line 8  Line 8 
8    
9  structure Probe : sig  structure Probe : sig
10    
11      val expand : MidIL.var * FieldDef.field_def * MidIL.var -> MidIL.assign list      val expand : {
12                result : MidIL.var,         (* result variable for probe *)
13                img : MidIL.var,            (* probe image argument *)
14                v : ImageInfo.info,         (* summary info about image *)
15                h : Kernel.kernel,          (* reconstruction kernel *)
16                k : int,                    (* number of levels of differentiation *)
17                pos : MidIL.var             (* probe position argument *)
18              } -> MidIL.assign list
19    
20    end = struct    end = struct
21    
# Line 26  Line 33 
33            DstV.new (prefix ^ Partials.axisToString(Partials.axis d), ty)            DstV.new (prefix ^ Partials.axisToString(Partials.axis d), ty)
34    
35      fun assign (x, rator, args) = (x, DstIL.OP(rator, args))      fun assign (x, rator, args) = (x, DstIL.OP(rator, args))
36      fun cons (x, args) = (x, DstIL.CONS args)      fun cons (x, args) = (x, DstIL.CONS(DstV.ty x, args))
37      fun realLit (x, i) = (x, DstIL.LIT(Literal.Float(FloatLit.fromInt i)))      fun realLit (x, i) = (x, DstIL.LIT(Literal.Float(FloatLit.fromInt i)))
38      fun intLit (x, i) = (x, DstIL.LIT(Literal.Int(IntInf.fromInt i)))      fun intLit (x, i) = (x, DstIL.LIT(Literal.Int(IntInf.fromInt i)))
39    
# Line 37  Line 44 
44              n, f,       (* Dst vars for integer and fractional components of position *)              n, f,       (* Dst vars for integer and fractional components of position *)
45              voxIter     (* iterator over voxels *)              voxIter     (* iterator over voxels *)
46            } (result, pdOp) = let            } (result, pdOp) = let
47            val vecsTy = DstTy.VecTy(2*s) (* vectors of coefficients cover support of kernel *)            val vecsTy = DstTy.vecTy(2*s) (* vectors of coefficients cover support of kernel *)
48            val vecDimTy = DstTy.VecTy dim            val vecDimTy = DstTy.vecTy dim
49          (* generate the variables that hold the convolution coefficients *)          (* generate the variables that hold the convolution coefficients.  The
50             * resulting list is in slowest-to-fastest axes order.
51             *)
52            val convCoeffs = let            val convCoeffs = let
53                  val Partials.D l = pdOp                  val Partials.D l = pdOp
54                  fun mkVar (_, []) = []                  fun mkVar (_, [], coeffs) = coeffs
55                    | mkVar (i, d::dd) = (case d                    | mkVar (i, d::dd, coeffs) = (case d
56                         of 0 => newVar_dim("h", i, vecsTy) :: mkVar(i+1, dd)                         of 0 => mkVar(i+1, dd, newVar_dim("h", i, vecsTy) :: coeffs)
57                          | 1 => newVar_dim("dh", i, vecsTy) :: mkVar(i+1, dd)                          | 1 => mkVar(i+1, dd, newVar_dim("dh", i, vecsTy) :: coeffs)
58                          | _ => newVar_dim(concat["d", Int.toString d, "h"], i, vecsTy) :: mkVar(i+1, dd)                          | _ => mkVar(i+1, dd, newVar_dim(concat["d", Int.toString d, "h"], i, vecsTy) :: coeffs)
59                        (* end case *))                        (* end case *))
60                  in                  in
61                    mkVar (0, l)                    mkVar (0, l, [])
62                  end                  end
63  val _ = print(concat["probeElem: ", Partials.partialToString pdOp, " in ", Int.toString(List.length convCoeffs), "D space\n"])  val _ = print(concat["probeElem: ", Partials.partialToString pdOp, " in ", Int.toString(List.length convCoeffs), "D space\n"])
64          (* for each dimension, we evaluate the kernel at the coordinates for that axis *)          (* for each dimension in space, we evaluate the kernel at the coordinates for that axis.
65             * the coefficients are
66             *      h_{s-i} (f - i) for 1-s <= i <= s
67             *)
68            val coeffCode = let            val coeffCode = let
69                  fun gen (x, k, (d, code)) = let                  fun gen (x, k, (d, code)) = let
70                        val d = d-1                      (* note that for 1D images, the f vector is a scalar *)
71                        val fd = newVar_dim ("f", d, DstTy.realTy)                        val fd = if (dim > 1)
72                                then newVar_dim ("f", d, DstTy.realTy)
73                                else f
74                        val a = DstV.new ("a", vecsTy)                        val a = DstV.new ("a", vecsTy)
75                        val tmps = List.tabulate(2*s,                      (* note that we reverse the order of the list since the convolution
76                              fn i => (DstV.new("t"^Int.toString i, DstTy.realTy), s - (i+1)))                       * space is flipped from the image space and we want the voxel vector
77                        fun mkArg ((t, n), code) = let                       * to be in increasing address order.
78                         *)
79                          val tmps = List.rev(List.tabulate(2*s,
80                                fn i => (DstV.new("t"^Int.toString i, DstTy.realTy), i - s)))
81                          fun mkArg ((t, 0), code) = (t, DstIL.VAR fd) :: code
82                            | mkArg ((t, n), code) = let
83                                val (rator, n) = if (n < 0) then (DstOp.Sub, ~n) else (DstOp.Add, n)
84                              val t' = DstV.new ("r", DstTy.realTy)                              val t' = DstV.new ("r", DstTy.realTy)
85                              in                              in
86                                realLit (t', n) ::                                realLit (t', n) ::
87                                assign (t, DstOp.Add DstTy.realTy, [fd, t']) ::                                assign (t, rator DstTy.realTy, [fd, t']) ::
88                                code                                code
89                              end                              end
90                        val code =                        val code =
91                              cons(a, List.map #1 tmps) ::                              cons(a, List.map #1 tmps) ::
92                              assign(x, DstOp.EvalKernel(2*s, h, k), [a]) ::                              assign(x, DstOp.EvalKernel(2*s, h, k), [a]) ::
93                                code                                code
94                        val code =                        val code = List.foldr mkArg code tmps
95                              assign(fd, DstOp.Select(DstTy.VecTy dim, d), [f]) ::                        val code = if (dim > 1)
96                                List.foldr mkArg code tmps                              then assign(fd, DstOp.Select(DstTy.vecTy dim, d), [f]) :: code
97                                else code
98                        in                        in
99                          (d, code)                          (d+1, code)
100                        end                        end
101                  val Partials.D l = pdOp                  val Partials.D l = pdOp
102                  in                  in
103                    #2 (ListPair.foldr gen (dim, []) (convCoeffs, l))                  (* we iterate from fastest to slowest axis *)
104                      #2 (ListPair.foldr gen (0, []) (convCoeffs, List.rev l))
105                  end                  end
106          (* generate the reduction code *)          (* generate the reduction code in reverse order *)
107            fun genReduce (result, [hh], IT.LF{vox, offsets}, code) =            fun genReduce (result, [hh], IT.LF{vox, offsets}, code) =
108                  assign (result, DstOp.Dot(2*s), [vox, hh]) :: code                  assign (result, DstOp.Dot(2*s), [vox, hh]) :: code
109              | genReduce (result, hh::r, IT.ND(_, kids), code) = let              | genReduce (result, hh::r, IT.ND(_, kids), code) = let
# Line 99  Line 121 
121              coeffCode @ reduceCode              coeffCode @ reduceCode
122            end            end
123    
124    (* generate code for probing the field (D^k (v * h)) at pos *)      fun doVoxelSample (result, v, k, s, diffIter, {h, n, f, img}, offset) = let
125      fun probe (result, (k, v, h), pos) = let            val stride = ImageInfo.stride
126            val ImageInfo.ImgInfo{dim, ty=([], ty), ...} = v            val dim = ImageInfo.dim v
127            val s = Kernel.support h            val vecsTy = DstTy.vecTy(2*s) (* vectors of coefficients cover support of kernel *)
128            val vecsTy = DstTy.VecTy(2*s) (* vectors of coefficients cover support of kernel *)          (* generate code to load the voxel data; since we use a vector load operation to load the
           val vecDimTy = DstTy.VecTy dim  
         (* generate the transform code *)  
           val x = DstV.new ("x", vecDimTy)      (* image-space position *)  
           val f = DstV.new ("f", vecDimTy)  
           val nd = DstV.new ("nd", vecDimTy)  
           val n = DstV.new ("n", DstTy.IVecTy dim)  
           val transformCode = [  
                   assign(x, DstOp.PosToImgSpace v, [pos]),  
                   assign(nd, DstOp.Floor dim, [x]),  
                   assign(f, DstOp.Sub vecDimTy, [x, nd]),  
                   assign(n, DstOp.TruncToInt dim, [nd])  
                 ]  
         (* generate the shape of the differentiation tensor with variables representing  
          * the elements  
          *)  
           val diffIter = let  
                 val partial = Partials.partial dim  
                 fun f (i, axes) = Partials.axis i :: axes  
                 fun g axes = let  
                         val r = DstV.new(  
                                 String.concat("r" :: List.map Partials.axisToString axes),  
                                 DstTy.realTy)  
                         in  
                           (r, partial axes)  
                         end  
                 in  
                   IT.create (k, dim, fn _ => (), f, g, [])  
                 end  
 val _ = let  
 val indentWid = ref 2  
 fun inc () = (indentWid := !indentWid + 2)  
 fun dec () = (indentWid := !indentWid - 2)  
 fun indent () = print(CharVector.tabulate(!indentWid, fn _ => #" "))  
 fun nd () = (indent(); print "ND\n");  
 fun lf (x, partial) = (  
       indent(); print(concat["LF(", DstV.toString x, ", ", Partials.partialToString partial, ")\n"]))  
 fun pr (Shape.ND(attr, kids)) = (nd attr; inc(); List.app pr kids; dec())  
   | pr (Shape.LF attr) = lf attr  
 in  
   print "diffIter:\n";  
   pr diffIter  
 end  
         (* generate code to load the voxel data; since we a vector load operation to load the  
129           * fastest dimension, the height of the tree is one less than the dimension of space.           * fastest dimension, the height of the tree is one less than the dimension of space.
130           *)           *)
131            val voxIter = let            val voxIter = let
# Line 181  Line 160 
160                              val t1 = DstV.new ("t1", DstTy.intTy)                              val t1 = DstV.new ("t1", DstTy.intTy)
161                              val t2 = DstV.new ("t2", DstTy.intTy)                              val t2 = DstV.new ("t2", DstTy.intTy)
162                              val (indices, code) = computeIndices (i+1, offsets)                              val (indices, code) = computeIndices (i+1, offsets)
163                              val code =                              val code = if (dim > 1)
164                                      then
165                                    intLit(t1, offset) ::                                    intLit(t1, offset) ::
166                                    assign(t2, DstOp.Select(DstTy.IVecTy dim, i), [n]) ::                                    assign(t2, DstOp.Select(DstTy.IVecTy dim, i), [n]) ::
167                                    assign(index, DstOp.Add(DstTy.intTy), [t1, t2]) ::                                    assign(index, DstOp.Add(DstTy.intTy), [t1, t2]) ::
168                                    code                                    code
169                                      else
170                                        intLit(t1, offset) ::
171                                        assign(index, DstOp.Add(DstTy.intTy), [t1, n]) ::
172                                        code
173                              val indices = index::indices                              val indices = index::indices
174                              in                              in
175                                (indices, code)                                (indices, code)
176                              end                              end
177                        val (indices, indicesCode) = computeIndices (0, offsets)                        val (indices, indicesCode) = computeIndices (0, offsets)
178                        val a = DstV.new ("a", DstTy.AddrTy)                        val a = DstV.new ("a", DstTy.AddrTy v)
179                        in                        in
180                          indicesCode @ [                          indicesCode @ [
181                              assign(a, DstOp.VoxelAddress v, indices),                              assign(a, DstOp.VoxelAddress(v, offset), img::indices),
182                              assign(vox, DstOp.LoadVoxels(ty, 2*s), [a])                              assign(vox, DstOp.LoadVoxels(v, 2*s), [a])
183                            ] @ code                            ] @ code
184                        end                        end
185                  in                  in
# Line 210  Line 194 
194                  in                  in
195                    List.foldr genProbeCode (cons (result, List.map getProbeVar kids) :: code) kids                    List.foldr genProbeCode (cons (result, List.map getProbeVar kids) :: code) kids
196                  end                  end
197              | genProbe (result, IT.ND(_, kids), code) = let              | genProbe (result, IT.ND(ty, kids), code) = let
198                  val tmps = List.tabulate(dim, fn i => DstV.new("t"^Int.toString i, DstTy.realTy))  (* FIXME: the type of the tmps depends on the types of the kids *)
199                    val tmps = List.tabulate(dim, fn i => DstV.new("t"^Int.toString i, ty))
200                  val code = cons(result, tmps) :: code                  val code = cons(result, tmps) :: code
201                  fun lp ([], [], code) = code                  fun lp ([], [], code) = code
202                    | lp (t::ts, kid::kids, code) = genProbe(t, kid, lp(ts, kids, code))                    | lp (t::ts, kid::kids, code) = genProbe(t, kid, lp(ts, kids, code))
# Line 220  Line 205 
205                  end                  end
206              | genProbe (result, IT.LF(t, pdOp), code) = (* for scalar fields *)              | genProbe (result, IT.LF(t, pdOp), code) = (* for scalar fields *)
207                  probeElem (result, pdOp) @ code                  probeElem (result, pdOp) @ code
208            val probeCode = genProbe (result, diffIter, [])            val probeCode = if (k > 0)
209                    then let
210                    (* for gradients, etc. we have to transform back to world space *)
211                      val ty = DstV.ty result
212                      val tensor = DstV.new("tensor", ty)
213                      val xform = assign(result, DstOp.TensorToWorldSpace(v, ty), [img, tensor])
214                      in
215                        genProbe (tensor, diffIter, [xform])
216                      end
217                    else genProbe (result, diffIter, [])
218            in            in
219  (* FIXME: for dim > 1 and k > 1, we need to transform the result back into world space *)  (* FIXME: for dim > 1 and k > 1, we need to transform the result back into world space *)
220              transformCode @ loadCode @ probeCode              loadCode @ probeCode
221            end            end
222    
223      fun expand (result, fld, pos) = let    (* generate code for probing the field (D^k (v * h)) at pos *)
224            fun expand' (result, FieldDef.CONV(k, v, h)) = probe (result, (k, v, h), pos)      fun expand {result, img, v, h, k, pos} = let
225  (* should push negation down to probe operation            val dim = ImageInfo.dim v
226              | expand' (result, FieldDef.NEG fld) = let            val s = Kernel.support h
227                  val r = DstV.new "value"            val vecsTy = DstTy.vecTy(2*s) (* vectors of coefficients to cover support of kernel *)
228                  val stms = expand' (r, fld)            val vecDimTy = DstTy.vecTy dim
229                  val ty = ??          (* generate the transform code *)
230              val x = DstV.new ("x", vecDimTy)      (* image-space position *)
231              val f = DstV.new ("f", vecDimTy)
232              val nd = DstV.new ("nd", vecDimTy)
233              val n = DstV.new ("n", DstTy.IVecTy dim)
234              val toImgSpaceCode = [
235                      assign(x, DstOp.PosToImgSpace v, [img, pos]),
236                      assign(nd, DstOp.Floor dim, [x]),
237                      assign(f, DstOp.Sub vecDimTy, [x, nd]),
238                      assign(n, DstOp.RealToInt dim, [nd])
239                    ]
240            (* generate the shape of the differentiation tensor with variables representing
241             * the elements
242             *)
243              val diffIter = let
244                    val partial = Partials.partial dim
245                    fun f (i, (_::dd, axes)) = (dd, Partials.axis i :: axes)
246                    fun labelNd (_::dd, _) = DstTy.tensorTy dd
247                    fun labelLf (_, axes) = let
248                            val r = DstV.new(
249                                    String.concat("r" :: List.map Partials.axisToString axes),
250                                    DstTy.realTy)
251                  in                  in
252                    expand' (r, fld) @ [assign(r, DstOp.Neg ty, [r])]                            (r, partial axes)
253                  end                  end
 *)  
             | expand' (result, FieldDef.SUM(fld1, dlf2)) = raise Fail "expandInside: SUM"  
254            in            in
255              expand' (result, fld)                    IT.create (k, dim, labelNd, f, labelLf, (List.tabulate(k, fn _ => dim), []))
256                    end
257    val _ = let
258    val indentWid = ref 2
259    fun inc () = (indentWid := !indentWid + 2)
260    fun dec () = (indentWid := !indentWid - 2)
261    fun indent () = print(CharVector.tabulate(!indentWid, fn _ => #" "))
262    fun nd ty = (indent(); print(concat["ND(", DstTy.toString ty, ")\n"]))
263    fun lf (x, partial) = (
264          indent(); print(concat["LF(", DstV.toString x, ", ", Partials.partialToString partial, ")\n"]))
265    fun pr (Shape.ND(attr, kids)) = (nd attr; inc(); List.app pr kids; dec())
266      | pr (Shape.LF attr) = lf attr
267    in
268      print "diffIter:\n";
269      pr diffIter
270    end
271              val vars = {h=h, n=n, f=f, img=img}
272              in
273                case ImageInfo.voxelShape v
274                 of [] => toImgSpaceCode @ doVoxelSample (result, v, k, s, diffIter, vars, 0)
275                  | [d] => let
276                      fun doSamples (offset, xs, code) = if (offset < 0)
277                            then code @ [cons(result, xs)]
278                            else let
279                              val res = DstV.new ("probe" ^ Int.toString offset, DstTy.realTy)
280                              val code = doVoxelSample (res, v, k, s, diffIter, vars, offset) @ code
281                              in
282                                doSamples (offset-1, res::xs, code)
283                              end
284                      in
285                        toImgSpaceCode @ doSamples (d-1, [], [])
286                      end
287                  | _ => raise Fail "image data with order > 1 not supported yet"
288                (* end case *)
289            end            end
290    
291    end    end

Legend:
Removed from v.1115  
changed lines
  Added in v.1116

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0