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

SCM Repository

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

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

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

revision 2413, Mon Aug 12 17:36:05 2013 UTC revision 2414, Mon Aug 19 05:02:14 2013 UTC
# Line 26  Line 26 
26      structure DstOp = MidOps      structure DstOp = MidOps
27      structure DstV = DstIL.Var      structure DstV = DstIL.Var
28      structure VMap = SrcIL.Var.Map      structure VMap = SrcIL.Var.Map
29        structure E=EinOp
30        structure EinOp= Operators
31      structure IT = Shape      structure IT = Shape
32    
33    (* generate a new variable indexed by dimension *)    (* generate a new variable indexed by dimension *)
# Line 34  Line 36 
36    
37      fun assign (x, rator, args) = (x, DstIL.OP(rator, args))      fun assign (x, rator, args) = (x, DstIL.OP(rator, args))
38    
39      fun assignEin (x, rator, xs) = (x, DstIL.EINAPP(rator, xs))      fun assignEin (x, rator, args) = (x, DstIL.EINAPP(rator, args))
40    
41      fun cons (x, args) = (x, DstIL.CONS(DstV.ty x, args))      fun cons (x, args) = (x, DstIL.CONS(DstV.ty x, args))
42      fun realLit (x, i) = (x, DstIL.LIT(Literal.Float(FloatLit.fromInt(IntInf.fromInt i))))      fun realLit (x, i) = (x, DstIL.LIT(Literal.Float(FloatLit.fromInt(IntInf.fromInt i))))
# Line 47  Line 49 
49            (* end case *))            (* end case *))
50      fun shapeVarToTensor sv = pruneShape sv      fun shapeVarToTensor sv = pruneShape sv
51    
52        fun createVec d= S.transform(EinOp.tensorOp,[[d]],[])
53        fun createdot(d)= S.transform(EinOp.innerProduct, [(0,[]),(0,[]),(0,[d])],[])
54    
55    
56                    (********************************)
57    
58    (* generate code for a evaluating a single element of a probe operation *)    (* generate code for a evaluating a single element of a probe operation *)
59      fun probeElem {      fun probeElem {
# Line 56  Line 61 
61              h, s,       (* kernel h with support s *)              h, s,       (* kernel h with support s *)
62              n, f,       (* Dst vars for integer and fractional components of position *)              n, f,       (* Dst vars for integer and fractional components of position *)
63              voxIter     (* iterator over voxels *)              voxIter     (* iterator over voxels *)
64    
65            } (result, pdOp) = let            } (result, pdOp) = let
66            val vecsTy = DstTy.vecTy(2*s) (* vectors of coefficients cover support of kernel *)            val vecsTy = createVec(2*s) (* vectors of coefficients cover support of kernel *)
67            val vecDimTy = DstTy.vecTy dim            val vecDimTy = createVec dim
68    
69          (* generate the variables that hold the convolution coefficients.  The          (* generate the variables that hold the convolution coefficients.  The
70           * resulting list is in slowest-to-fastest axes order.           * resulting list is in slowest-to-fastest axes order.
71           *)           *)
72    
73    
74            val convCoeffs = let            val convCoeffs = let
75                  val Partials.D l = pdOp                  val Partials.D l = pdOp
76                  fun mkVar (_, [], coeffs) = coeffs                  fun mkVar (_, [], coeffs) = coeffs
# Line 73  Line 82 
82                  in                  in
83                    mkVar (0, l, [])                    mkVar (0, l, [])
84                  end                  end
         (* for each dimension in space, we evaluate the kernel at the coordinates for that axis.  
          * the coefficients are  
          *      h_{s-i} (f - i) for 1-s <= i <= s  
          *)  
           val coeffCode = let  
                 fun gen (x, k, (d, code)) = let  
                     (* note that for 1D images, the f vector is a scalar *)  
                       val fd = if (dim > 1)  
                             then newVar_dim ("f", d, DstTy.realTy)  
                             else f  
                       val a = DstV.new ("a", vecsTy)  
                     (* note that we reverse the order of the list since the convolution  
                      * space is flipped from the image space and we want the voxel vector  
                      * to be in increasing address order.  
                      *)  
                       val tmps = List.rev(List.tabulate(2*s,  
                             fn i => (DstV.new("t"^Int.toString i, DstTy.realTy), i - s)))  
                       fun mkArg ((t, 0), code) = (t, DstIL.VAR fd) :: code  
                         | mkArg ((t, n), code) = let  
   
                                 (*Note ISub, and IAdd no longer have a type, do they need ~n, and n*)  
                                 (*val (rator, n) = if (n < 0) then (DstOp.ISub, ~n) else (DstOp.IAdd, n)*)  
   
                             val (rator, n) = case n  
                                                 of [e1] => if (n < 0) then (DstOp.ISub, ~n) else (DstOp.IAdd, n)  
                                         |_ =>  let  
                                            val shape = shapeVarToTensor sv  
                                                    val operator = EinOp.addTensors  
                                           in  
   
                                              DSTIL.EINAPP(S.transform(operator,[len(shape), shape]), n )  
                                           end  
   
   
                             val t' = DstV.new ("r", DstTy.realTy)  
                             in  
                               realLit (t', n) ::  
                               assign (t, rator DstTy.realTy, [fd, t']) ::  
                               code  
                             end  
                       val code =  
                             cons(a, List.map #1 tmps) ::  
                             assign(x, DstOp.EvalKernel(2*s, h, k), [a]) ::  
                               code  
                       val code = List.foldr mkArg code tmps  
                       val code = if (dim > 1)  
                             then assign(fd, DstOp.Index(DstTy.vecTy dim, d), [f]) :: code  
                             else code  
                       in  
                         (d+1, code)  
                       end  
                 val Partials.D l = pdOp  
                 in  
                 (* we iterate from fastest to slowest axis *)  
                   #2 (ListPair.foldr gen (0, []) (convCoeffs, List.rev l))  
                 end  
85    
                 fun createdot(d)= S.transform(EinOp.innerProduct, [(0,[]),(0,[]),(0,[d])])  
86    
87    
88    
         (* generate the reduction code in reverse order *)  
         (*assign (result, DstOp.Dot(2*s), [vox, hh]) :: code*)  
           fun genReduce (result, [hh], IT.LF{vox, offsets}, code) =  
                         assignEin (result, createdot(2*s), [vox, hh]) :: code  
             | genReduce (result, hh::r, IT.ND(_, kids), code) = let  
                 val tv = DstV.new ("tv", vecsTy)  
                 val tmps = List.tabulate(2*s, fn i => DstV.new("t"^Int.toString i, DstTy.realTy))  
                 fun lp ([], [], code) = code  
                   | lp (t::ts, kid::kids, code) = genReduce(t, r, kid, lp(ts, kids, code))  
89    
                 (*val code = cons(tv, tmps) :: assign(result, Dst.Dot(2*s), [hh, tv]) :: code*)  
                 val code = cons(tv, tmps) :: assignEin(result, createDot(2*s), [hh, tv]) :: code  
90    
91                  in                                          (********************************)
92                    lp (tmps, kids, code)      fun doVoxelSample (result, v, k, s, deltas, {h, n, f, img}, offset) = let
                 end  
             | genReduce _ = raise Fail "genReduce"  
           val reduceCode = genReduce (result, convCoeffs, voxIter, [])  
           in  
             coeffCode @ reduceCode  
           end  
   
     fun doVoxelSample (result, v, k, s, diffIter, {h, n, f, img}, offset) = let  
93            val stride = ImageInfo.stride            val stride = ImageInfo.stride
94            val dim = ImageInfo.dim v            val dim = ImageInfo.dim v
95            val vecsTy = DstTy.vecTy(2*s) (* vectors of coefficients cover support of kernel *)            val vecsTy = createVec(2*s) (* vectors of coefficients cover support of kernel *)
96    
97          (* generate code to load the voxel data; since we use a vector load operation to load the          (* generate code to load the voxel data; since we use a vector load operation to load the
98           * 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.
99           *)           *)
# Line 172  Line 106 
106                  in                  in
107                    IT.create (dim-1, 2*s, fn _ => (), f, g, ([], []))                    IT.create (dim-1, 2*s, fn _ => (), f, g, ([], []))
108                  end                  end
109    
110    
111            val loadCode = let            val loadCode = let
112                  fun genCode ({offsets, vox}, code) = let                  fun genCode ({offsets, vox}, code) = let
113                        fun computeIndices (_, []) = ([], [])                        fun computeIndices (_, []) = ([], [])
# Line 205  Line 141 
141                  in                  in
142                    IT.foldr genCode [] voxIter                    IT.foldr genCode [] voxIter
143                  end                  end
144    
145          (* generate code to evaluate and construct the result tensor *)          (* generate code to evaluate and construct the result tensor *)
146    
147            val probeElem = probeElem {dim = dim, h = h, s = s, n = n, f = f, voxIter = voxIter}            val probeElem = probeElem {dim = dim, h = h, s = s, n = n, f = f, voxIter = voxIter}
148    
149                    (*Used for result, *)
150    
151        (*Node, next to leaf*)
152    
153            fun genProbe (result, IT.ND(_, kids as (IT.LF _)::_), code) = let            fun genProbe (result, IT.ND(_, kids as (IT.LF _)::_), code) = let
               (* the kids will all be leaves *)  
154                  fun genProbeCode (IT.LF arg, code) = probeElem arg @ code                  fun genProbeCode (IT.LF arg, code) = probeElem arg @ code
155                  fun getProbeVar (IT.LF(t, _)) = t                  fun getProbeVar (IT.LF(t, _)) = t
156                  in                  in
157                    List.foldr genProbeCode (cons (result, List.map getProbeVar kids) :: code) kids                    List.foldr genProbeCode (cons (result, List.map getProbeVar kids) :: code) kids
158                  end                  end
159    
160        (*Node next to node*)
161    
162              | genProbe (result, IT.ND(ty, kids), code) = let              | genProbe (result, IT.ND(ty, kids), code) = let
163  (* FIXME: the type of the tmps depends on the types of the kids *)  
164                  val tmps = List.tabulate(dim, fn i => DstV.new("t"^Int.toString i, ty))                  val tmps = List.tabulate(dim, fn i => DstV.new("t"^Int.toString i, ty))
165                  val code = cons(result, tmps) :: code                  val code = cons(result, tmps) :: code
166                  fun lp ([], [], code) = code                  fun lp ([], [], code) = code
# Line 223  Line 168 
168                  in                  in
169                    lp (tmps, kids, code)                    lp (tmps, kids, code)
170                  end                  end
171            (*Leaf*)
172              | genProbe (result, IT.LF(t, pdOp), code) = (* for scalar fields *)              | genProbe (result, IT.LF(t, pdOp), code) = (* for scalar fields *)
173                  probeElem (result, pdOp) @ code                  probeElem (result, pdOp) @ code
174            val probeCode = if (k > 0)  
175    
176    
177    (*Analyze *)
178    
179    
180                        (**********     trasform to world space***********)
181              val probeCode = if (*(k > 0)*)
182                length(deltas)>0
183                  then let                  then let
184                  (* for gradients, etc. we have to transform back to world space *)                  (* for gradients, etc. we have to transform back to world space *)
185                    val ty = DstV.ty result                    val ty = DstV.ty result
186                    val tensor = DstV.new("tensor", ty)                    val tensor = DstV.new("tensor", ty)
187                    val xform = assign(result, DstOp.TensorToWorldSpace(v, ty), [img, tensor])  
188    
189    
190                val alpha= List.take(dim, length(dim)-1)
191                val ilist=  [alpha,  tl(tensor), hd(tensor)]
192                val TensorToWorldSpace=S.tranform(EinOp.innerProduct, ilist,[])
193                val xform = assignEin(result, TensorToWorldSpace, [img, tensor])
194                    in                    in
195                      genProbe (tensor, diffIter, [xform])                      genProbe (tensor, [xform])
196                    end                    end
197                  else genProbe (result, diffIter, [])                  else genProbe (result, [])
198            in            in
199  (* FIXME: for dim > 1 and k > 1, we need to transform the result back into world space *)          probeCode
200              loadCode @ probeCode              (*loadCode @ probeCode*)
201            end            end
202    
203     fun createVec(d)= S.transform(EinOp.tensorOp,[[d]])  (****************************************************************************)
204    
205    (*    from EinOps     of (kern, deltas), x)
206              arguments   of fld-> (img->(v), h->(h,k))
207                             pos
208    *)
209    
210    
211    (* generate code for probing the field (D^k (v * h)) at pos *)    (* generate code for probing the field (D^k (v * h)) at pos *)
212      fun expand {result, img, v, h, k, pos} = let      fun expandEin {result, img, v, h, k, pos,deltas,index} = let
213            val dim = ImageInfo.dim v            val dim = ImageInfo.dim v
214            val s = Kernel.support h            val s = Kernel.support h
215            val vecsTy =createVec(2*s)            val vecsTy =createVec(2*s)
216              val vecDimTy = createVec(dim)
217                  (*DstTy.vecTy(2*s)  vectors of coefficients to cover support of kernel *)        val translate=DstOp.Translate v
218          val transform=DstOp.Transform v
           val vecDimTy = createVec(dim)     (*DstTy.vecTy dim*)  
219    
220          (* generate the transform code *)          (* generate the transform code *)
221            val x = DstV.new ("x", vecDimTy)      (* image-space position *)            val x = DstV.new ("x", vecDimTy)      (* image-space position *)
222            val f = DstV.new ("f", vecDimTy)            val f = DstV.new ("f", vecDimTy)
223            val nd = DstV.new ("nd", vecDimTy)            val nd = DstV.new ("nd", vecDimTy)
224            val n = DstV.new ("n", DstTy.iVecTy dim)            val n = DstV.new ("n", DstTy.iVecTy dim)
225          val M = DstV.new ("M", transform)
226          val T = DstV.new ("T", translate)
227    
228          val sub= S.transform(EinOp.subTensor,[dim],[])
229    
230    
231           (* M_ij x_i*)
232          val MXop=S.transform(EinOp.innerProduct,[[dim],[],[dim]],[])
233          val MX = DstV.new ("MX", MXop)
234    
235    
236    
237          val PosToImgSpace=S.transform(EinOp.addTensor,[[dim]],[])
238    
239    
240            val toImgSpaceCode = [            val toImgSpaceCode = [
241                    assign(x, DstOp.PosToImgSpace v, [img, pos]),            assignEin(MX, Mxop, [M,pos]), (*Just added*)
242              assignEin(x, PosToImgSpace,[MX,T])
243                    assign(nd, DstOp.Floor dim, [x]),                    assign(nd, DstOp.Floor dim, [x]),
244                    assign(f, DstOp.Sub vecDimTy, [x, nd]),                    assignEin(f, sub,[x,nd]),
245                    assign(n, DstOp.RealToInt dim, [nd])                    assign(n, DstOp.RealToInt dim, [nd])
246                  ]                  ]
247          (* generate the shape of the differentiation tensor with variables representing  
248           * the elements  
249            (*
250    
251    
252            This return an einExip, kernels are represented as scalar tensor in the epression, and
253            the arguments for kernels are midOps-that have the kernel, direction and differentiation.
254    
255            Conv(h, delta)
256                so look at deltas
257           *)           *)
258            fun diffIter () = let  
259                  val partial = Partials.partial dim  
260                  fun f (i, (_::dd, axes)) = (dd, Partials.axis i :: axes)        (* dim of kernel dimK*)
261                  fun labelNd (_::dd, _) = DstTy.tensorTy dd  
262                  fun labelLf (_, axes) = let          (*maybe this should be somewhere else*)
263                          val r = DstV.new(      fun evalDelta(_,[])= 0
264                                  String.concat("r" :: List.map Partials.axisToString axes),        | evalDelta(i, E.Delta(_,j)::dels)=
265                                  DstTy.realTy)              if (i==j) then 1 + evalDelta(i,dels)
266                          in              else evalDelta(i,dels)
267                            (r, partial axes)  
268                          end  
269                  in  
270                    IT.create (k, dim, labelNd, f, labelLf, (List.tabulate(k, fn _ => dim), []))  
271                  end      fun evalPosition(position)=let
272            val vars = {h=h, n=n, f=f, img=img}  
273            in          fun generate(0, body, param, args)=
274              case ImageInfo.voxelShape v              let
275               of [] => toImgSpaceCode @ doVoxelSample (result, v, k, s, diffIter(), vars, 0)                  val k=evalDelta(0 ,deltas)
276                    val x= DstOp.EvalKernel(2*s, h, 0, k)
277    
278                    val arg= assign(v, x, position[0])
279                in args@ [arg] end
280    
281            (* (body@[E.Tensor(id,[])],  param@[E.TEN], args@arg) end*)
282    
283            | generate(i, body, param, args)=
284                let
285                    val k=evalDelta(i ,deltas)
286                    val x= DstOp.EvalKernel(2*s, h, i, k)
287    
288                    val arg= assign(v, x, position[i])
289                in   generate(i-1, body@[E.Tensor(id,[])],  param@[E.TEN], args@[arg]) end
290    
291            val (body, param, args)=generate(dimk, [],[],[])
292    
293            val einexp=E.EIN{
294                    params=param @ [E.FLD, E.TEN]
295                    index=[],
296                    body= E.Prod body @[E.Field(id, [dim]), E.Tensor(id,[])]
297              }
298    
299            val r=S.transform(EinOp.Probe,[dimk])
300            val t=R.App(r, [img, position])
301            val t'=R.App(einexp, args@ [t])
302            in  t' end
303    
304    
305    
306  (*  (*
307                | [d] => let      call evalPosition on each position
308                  (* the result will be a vector of k-order tensors; each element of the vector      val positionE=evalPosition(position)
309                   * has the sampleTy = tensor[dim,...,dim].     val e= S.transform(EinOp.AddTensor,dim)
310        in R.App(e, positionE) end
311                   *)                   *)
312                    val sampleTy = DstTy.TensorTy(List.tabulate(k, fn _ => dim))  
313                    fun doSamples (offset, xs, code) = if (offset < 0)  
314                          then code @ [cons(result, xs)]  
315                          else let  
316                            val res = DstV.new ("probe" ^ Int.toString offset, sampleTy)      (*using sum hmm*)
317                            val code = doVoxelSample (res, v, k, s, diffIter(), vars, offset) @ code      fun generate( paramk, indexk, bodyk, argk,0)=
318                            in          let
319                              doSamples (offset-1, res::xs, code)             val einexp= E.EIN{
320                            end                  params = paramk @ [E.FLD(dim), E.TEN],
321                    index = indexk,
322                    body = E.SUM(dimk, E.Prod(bodyk@[E.Probe(E.Field(dim), E.Tensor(dimk+1,[]))]))
323                }
324                val args=argk @ [img, pos]
325            in R.APP(einexp, args) end
326    
327          | generate( paramk, indexk, bodyk, argk,direction)=
328            let
329                val deriv=evalDelta(deltas,direction)
330                val arg=DStOp.EvalKernel(2*s, h, direction, deriv),[pos]
331                val next=direction-1
332                    in                    in
333                      toImgSpaceCode @ doSamples (d-1, [], [])              generate(paramk@[E.TEN], indexk@[E.SX(s-1)], bodyk@[E.Tensor(next, [])], argk@[arg],next)
334                    end                    end
335  *)  
336                | shape => let  
337                  (* the result will be a d1 x d2 matrix of k-order tensors; each element of the matrix  
338                   * has the sampleTy = tensor[dim,...,dim].      (*Add each tensors*)
                  *)  
                   val sampeShape = List.tabulate(k, fn _ => dim)  
                   fun gen (y, d::dd, offset, code) = let  
                         val prefix = DstV.name y  
                         val xs = List.tabulate(d,  
                               fn i => DstV.new(  
                                 concat[prefix, "_", Int.toString i],  
                                 DstTy.TensorTy(dd @ sampeShape)))  
                         val code = cons(y, xs) :: code  
                         in  
                           List.foldr (fn (x, (off, cd)) => gen(x, dd, off, cd)) (offset, code) xs  
                         end  
                     | gen (y, [], offset, code) =  
                         (offset-1, doVoxelSample (y, v, k, s, diffIter(), vars, offset) @ code)  
                   val (_, code) = gen (result, shape, ImageInfo.stride v - 1, [])  
339                    in                    in
                     toImgSpaceCode @ code  
                   end  
             (* end case *)  
           end  
340    
341    
342        generate([],[],[], [],dimk)
343    
344    end
345    end    end

Legend:
Removed from v.2413  
changed lines
  Added in v.2414

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