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

SCM Repository

[diderot] View of /branches/vis15/src/compiler/mid-to-low/eval-img.sml
ViewVC logotype

View of /branches/vis15/src/compiler/mid-to-low/eval-img.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3771 - (download) (annotate)
Mon Apr 25 18:37:52 2016 UTC (3 years, 8 months ago) by cchiw
File size: 8676 byte(s)
split evalImg into steps
(* eval-img.sml
 *
 * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
 *
 * COPYRIGHT (c) 2016 The University of Chicago
 * All rights reserved.
 *)

structure EvalImg : sig

 (* expand a MidIR probe to LowIR code.  The arguments are:
  *
  *    avail   -- available LowIR assignments
  *    mapp    -- mapping from iteration indices to deBruijn indices
  *    sx      -- summation bounds
  *    imgexp  -- ein expression for image expression
  *    args    -- the actual arguments of the enclosing Ein expression
  *)
    val expand : {
	      avail : AvailRHS.t,
	      mapp : int IntRedBlackMap.map,
	      sx : Ein.sumrange list,
	      imgexp : Ein.ein_exp,
	      args : LowIR.var list
	  }  -> LowIR.var list

  end = struct

    structure Op = LowOps
    structure Ty = LowTypes
    structure IR = LowIR
    structure Var = IR.Var
    structure E = Ein
    structure P = EinPP
    structure Mk = MkLowIR
    structure IMap = IntRedBlackMap

    fun assignOP (avail, opss, args, pre, ty) = AvailRHS.addAssign(avail, pre, ty, IR.OP(opss, args))
    fun mkAddPtr (avail, args, ty) = assignOP (avail, Op.IAdd, args, "addPtr", ty)
    fun mkProdInt (avail, args) = assignOP (avail, Op.IAdd, args, "prodInt", Ty.IntTy)
    fun mkInt (avail, n) =  Mk.intLit(avail, IntInf.fromInt n)

  (* The image "vImg" is probed at positions
  * Σ_{sx} V_alpha[pos0::px]
  * sumPos () iterates over the summation indices and creates a mapp for the indicies
  * once mapp (j->2 k->0) is created sumPos () calls createImgVar () to get the addr
  * of Σ_k V_{i}[T_j, T_k] createImgVar () uses mkpos (), getPosAddr (), and
  * getImgAddr () to get imgvar 
  *) 
    fun expand{avail, mapp, sx, imgexp, args} = let
	  val E.Img(imgId, v_alpha, pos0::px, s, border) = imgexp
	  val range = 2*s
	  val lb = 1-s
        (* get the image argument *)
	  val vImg = List.nth(args, imgId)
	  val imgInfo = (case IR.Var.getDef vImg
		 of IR.OP(Op.LoadImage(Ty.ImageTy img, _), _) => img
		  | IR.GLOBAL gv => raise Fail "FIXME: input variable"
		  | _ => raise Fail "unable to get image argument"
		(* end case *))
	  val dim = ImageInfo.dim imgInfo
	  val ptyTy = Ty.AddrTy imgInfo
	  val sizes = ImageInfo.sizes imgInfo
        (*base address*)
	  val vBase = assignOP (avail, Op.BaseAddress imgInfo, [vImg], "baseAddr", ptyTy)
        (*shift of the image field.*)
	  val vShapeShift = mkInt (avail, foldl (fn (a, b) => b*a)  1 (ImageInfo.voxelShape imgInfo))
        (* Since the image is loaded as a vector
	 * we evaluate the first position just once
	 * Σ_{ij..} V[T+i, T+j...]-> Σ_{j..} V[T+j...]
	 * and we drop the first summation index
	 * Additionally, summation indices are reversed
	 * that inner loop is second (y)  axis and outer loop is third (z) axis
	 *) 
	  val (vPos0, sxx) = let
		val E.Opn(E.Add, [E.Tensor (id, ix), _ ]) = pos0
		val vA = Mk.tensorIndex (avail, mapp, List.nth (args, id), ix)
		val vB = mkInt (avail, lb)
		val vC = Mk.realAdd (avail, vA, vB)
		val sxx = List.revMap (fn (E.V sid, _, _) => sid) (List.tl sx)
		in
		  (vC, sxx)
		end
        (* mkpos:ein_exp list*var list*IR.Mk.assignOP list
	 * transform ein_exp to low-il
	 * returns var for the position
	 *) 
	  fun mkpos (e, mapp, rest) = (case e
	         of [] => List.rev rest
		  | (E.Opn(E.Add, ([E.Tensor (id, [E.C(c)]), E.Value v1])) :: es) => let
		      val vA = Mk.tensorIndex (avail, mapp, List.nth (args, id), [E.C c])
		      val rest' = (case Mk.lookupIdx (mapp, v1)
			     of 0 => vA
			      | j => Mk.realAdd (avail, vA, mkInt (avail, j))
			    (* end case *)) 
		      in
			mkpos (es, mapp, rest' :: rest)
		      end
		  | e1 :: _ => raise Fail ("Incorrect pos for Image: " ^ P.expToString e1) 
		(* end case *))
        (* getPosAddr:var list->var*IR.Mk.assignOP list
	 * create position addr based on image info's shapeshift, image info's sizes, and args
	 * args are the variables for this specific positions. V_ ([x, y]) 
	 * returns vPosAddr,
	 *) 
	  fun getPosAddr args = (case (sizes, args)
		 of ([_], [i]) => mkProdInt (avail, [vShapeShift, i])  (*1-d*)
		  | ([x, _], [i, j]) => let  (*2-d*) 
		      val vA = mkInt (avail, x)
		      val vB = mkProdInt (avail, [vA, j])
		      val vC = Mk.intAdd (avail, i, vB)
		      in
			mkProdInt (avail, [vShapeShift, vC])
		      end
		  | ([x, y, _], [i, j, k]) => let  (*3-d*)
		      val vA = mkInt (avail, y)
		      val vB = mkProdInt (avail, [vA, k])
		      val vC = Mk.intAdd (avail, j, vB)
		      val vD = mkInt (avail, x)
		      val vE = mkProdInt (avail, [vD, vC])
		      val vF = Mk.intAdd (avail, i, vE)
		      in
			mkProdInt (avail, [vShapeShift, vF])
		      end
		  | _ => raise Fail "getPosAddr: invalid dimension"
		(* end case *))
	  fun indexImageShape [] = 0
	    | indexImageShape [i] = i
	    | indexImageShape [i, j] = let
		val [a, b] = ImageInfo.voxelShape imgInfo
		in
		  (b*j) + i
		end
	    | indexImageShape  _ = raise Fail "Image shape not supported"
        (* getImgAddr:int list *var->var*IR.Mk.assignOP list
	 * creates image address with ^position address, imgType, and base address
	 * imgType are  image specific indices V[0, 1] (_)
	 * ->returns (vImgAddr, ImgAddrcode) 
	 *) 
	  fun getImgAddr (imgType, vPosAddr) = (case imgType
		 of [] => mkAddPtr (avail, [vBase, vPosAddr], ptyTy) 
		  | [0] => mkAddPtr (avail, [vBase, vPosAddr], ptyTy)
		  | _ => let
		      val vA = mkAddPtr (avail, [vBase, vPosAddr], ptyTy)
		      val vB = mkInt (avail, indexImageShape imgType)
		      in
			mkAddPtr (avail, [vB, vA], ptyTy)
		      end
		(* end case *))
        (* createImgVar:dict->var*IR.Mk.assignOP list
	 *  gets low-il var for loading an image address
	 *) 
	  fun createImgVar mapp = let
	      (* transforms the probed position to low-il *)
		val vAs = mkpos (px, mapp, [])
	      (* adds intial position to ^*)
		val posArgs = vPos0::vAs
	      (*img specific index*)
		val imgType = List.map (fn e1 => Mk.lookupMu (mapp, e1)) v_alpha
		val vImgAddr = (case border
		       of E.None => let
                    val B = getPosAddr posArgs       (* shift addr based on imageInfo size *)
                    val C = getImgAddr (imgType, B)  (* shift addr based on alpha *)
                    in
                        C
                    end
			| _ => let
			  (* transforms border control and creates controlIndex wrapper *)
			    val ictl = (case border
				   of E.Clamp => IndexCtl.Clamp
				    | E.Mirror => IndexCtl.Mirror
				    | E.Wrap => IndexCtl.Wrap
				    | E.Default => raise Fail "Default boarder control")
			  (* img var, offset img address, border *)
			    fun controlIndex ([], n) = []
			      | controlIndex (e1::es, n) =
				  assignOP (
				    avail, Op.ControlIndex(imgInfo, ictl, n), [vImg, e1],
				    "cntrl"^Int.toString n, Ty.realTy
				  ) :: controlIndex(es, n+1)

                                                   (* Given EIN term V_alpha(e1, e2, e3) *)
                                                   (* posArgs creates variables for terms e1 ... *)
                val A = controlIndex(posArgs, 0)   (* wraps control around e1 ... *)
                val B = getPosAddr A               (* shift addr based on imageInfo size *)
                val C = getImgAddr (imgType, B)    (* shift addr based on alpha *)
                in
                    C
			    end

(* to create  voxel address with control
			    val op1 = Op.VoxelAddressWithCtl(imgInfo, indexImageShape imgType, ictl)
			    in
			       assignOP(avail, op1,  vImg::posArgs, "voxeladdresswithcontrol", ptyTy)
			    end
*)
			(* end case *))
		in
		  assignOP (avail, Op.LoadVoxel imgInfo, [vImgAddr], "vox", Ty.tensorTy [range])
		end
	  val rangeList = List.tabulate (range, fn e => e)
	(* sumPos:index_id * var list*LowIR.Mk.assignOP list*dict*int
	 * ->var*LowIR.Mk.assignOP list
	 * sumPos iterates over the summation indices and creates mapp
	 *) 
	  fun sumPos ([], rest, dict, _) = createImgVar dict :: rest
	    | sumPos ([sid], rest, dict, [r]) = let
		val n' = lb+r
		in
		  createImgVar (IMap.insert (dict, sid, n')) :: rest
		end
	    | sumPos ([sid], rest, dict, r::es) = let
		val n' = lb+r
		val rest' = createImgVar (IMap.insert (dict, sid, n'))
		in
		  sumPos ([sid], rest'::rest, dict, es)
		end
	    | sumPos (sid::sxx, rest, dict, [r]) = let
		val n' = lb+r
		in
		  sumPos (sxx, rest, IMap.insert (dict, sid, n'), rangeList)
		end
	    | sumPos (sid::sxx, rest, dict, r::es) = let
		val n' = lb+r
		val rest' = sumPos (sxx, rest, IMap.insert (dict, sid, n'), rangeList)
		in
		  sumPos (sid::sxx, rest', dict, es)
		end
	  val ids = sumPos (sxx, [], mapp, rangeList)
	  in
	    List.rev ids
	  end

  end

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