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

SCM Repository

[diderot] View of /branches/charisee/src/compiler/tree-il/lowOp-to-treeOp.sml
ViewVC logotype

View of /branches/charisee/src/compiler/tree-il/lowOp-to-treeOp.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3169 - (download) (annotate)
Sun Mar 29 22:17:50 2015 UTC (6 years, 8 months ago) by jhr
File size: 12365 byte(s)
  working on fixing initialization of inputs
(*This function transitions low-il operators to tree-il operators
    When there is a LowIL vector op then it breaks it into HW supported TreeIL vector operation
    i.e. A6+B6=> Mux[A4+B4, A2+B2]
    The following variables are used
    isAligned/A:bool-Is the array aligned
    isFill:bool-Is the vector filled with zeros i.e. length 3 vectors represented with length 4
    nSize: int -The Size of the vector operation, (4)
    oSize:int-The Size of the orginal arguments in vector operation if less than new Size.  (3)
    pieces: sizes of vector operations. i.e.2->[2], 6->[4,2]   3->[4]
*)

(* FIXME: add signature!!! *)
structure LowOpToTreeOp =
  struct
    local
      structure Src = LowIL
      structure SrcOp = LowOps
      structure SrcTy = LowILTypes
      structure SrcV = Src.Var
      structure DstOp = TreeOps
      structure DstTy = TreeILTypes
      structure Dst = TreeIL
      structure DstSV=Dst.StateVar
      structure DstV = Dst.Var
      structure Ty=TreeIL.Ty
    in

    val testing=1
    fun testp t=(case testing
        of 1=>(print(String.concat t);1)
         |_ =>1
    (*end case*))

    (**************************************)
    (* isAlignedLoad: bool* ty->bool
    * Do we Load this array assuming it's aligned?
    * Decides if isAligned is true when creating E_load
    * Currently, it is only true when the vector argument can be represent in the HW
    * Fix here
    *)
    fun isAlignedLoad(isFill,Ty.TensorTy [_]) =(case isFill
        of true => false
        | _     => true
        (*end case*))
    | isAlignedLoad _ =false

    (* isAlignedStore: bool*int->bool
    * Do we Store this array assuming it's aligned?
    * Decides if isAligned is true when creating S_Store and E_Mux
    * Currently, it is false always 
    * Fix here
    *)
    fun (*isAlignedStore(isFill,1) =(case isFill
        of true => false
        | _     => true
    (*end case*))
    |*)isAlignedStore _ =false(*true*)

    (**************************************)
    (*mkStmt:TreeIL.Var* TreeIL.Var.kind*MidIL.Op*bool*int*bool*ty*TreeIL.Exp list ->TreeIL.stmt
    * makes final TreeIL.Stmt
    * When TreeIL.Op is a sumVec is then all ops are added
    * If lhs is a global then S_Store is used
    * Otherwise uses S_Assign
    *)
    fun mkStmt(lhs,lhsKind,origrator,isFill,oSize,A,splitTy,ops)= (case origrator
        of SrcOp.sumVec _ => Dst.S_Assign([lhs], addSca ops)
        | _               => (case lhsKind
            of TreeIL.VK_Local  =>  Dst.S_Assign([lhs], Dst.E_Mux(A,isFill,oSize,splitTy,ops))
            | _     => Dst.S_StoreVec(Dst.E_Var lhs,0,A,isFill,oSize,Ty.TensorTy[oSize],splitTy, ops)
            (*end case*))
        (*end case*))
    and addSca [e1]=e1
    | addSca(e1::e2::es)= addSca([Dst.E_Op(DstOp.addSca,[e1,e2])]@es)



    (**************************************)
    (*getArg:bool*TreeILVar.kind*TreeIL.Exp*int*int*int*int->TreeIL.Exp
    *  Gets the argument for the operation 
    *  if the argument is a mux then we get the piece needed for the operation
    *  if the argument is a local var then we assume it is the right size
    *  if the argument is a global var or state var then we load the array with offset and sizes
    *  otherwise the arg was not loaded probably and should produce an error 
    *)
    fun getArg(isFill,lhsKind,t,count, nSize, oSize,offset)=(case t
        of (Dst.E_Var a) =>(case (DstV.kind a)
            of TreeIL.VK_Local =>t
            | _  => Dst.E_LoadArr(isAlignedLoad(isFill,DstV.ty a) ,nSize,oSize,t, Dst.E_Lit(Literal.Int offset))
            (*end case*))
        | (Dst.E_State a)=> Dst.E_LoadArr(isAlignedLoad(isFill,DstSV.ty a) ,nSize,oSize,t, Dst.E_Lit(Literal.Int offset))
        | (Dst.E_Mux(_,_,_,_,ops))=> List.nth(ops,count)
        | a1 =>( print(String.concat["Warning argument to vector operation is: ",Dst.toString a1]);a1)
        (*|  a1 = raise Fail("Arg to vector op is not Mux or Var. Found: "^Dst.toString a1)*)
        (*end case*))


    (* mkGenericOps:bool.TreeIL.Var.kind*LowILOP*TreeILOP*int*int list*TreeILExp*TreeILExp*int->TreeILExp List
        Take the original vector op and breaks it "pieces" which are HW supported sizes
        gets arguments with getArg(). 
        and then puts them inside TreeIL op ("rator")
        special case sumVecOp, because it maintains new and old size.
        
    *)
    fun mkGenericOps(isFill,lhsKind,oldrator,rator,oSize,pieces,argScas,argVecs,indexAt)= let
        (*createOps:int list*int*int*DstIL.exp->DstIL.exp list
        *  Gets all the Arguments in order
        *   i.e. nsize=[4,2]=>  [[A4,B4],[A2,B2]]
        *)
        fun createOps ([], _,_, code) = code
        | createOps (nSize::es, count,offset, code)=let
            val argsLd =List.map (fn a =>getArg(isFill,lhsKind,a,count, nSize, oSize, offset))  argVecs
            val exp = (nSize, argScas@argsLd)
            in
                createOps (es, count+1,offset + IntInf.fromInt nSize, code@[exp])
            end
        in (case (oldrator,pieces,argVecs)
            of   (SrcOp.sumVec _,[nSize],[a]) =>let
                val args=[getArg(isFill,lhsKind,a,0, nSize, oSize, (0))]
                in
                    [Dst.E_Op(DstOp.sumVec([nSize],oSize),args)]
                end
            | (SrcOp.sumVec _,_,_) =>let
                val code=createOps (pieces, 0,indexAt, [])
                val args=List.foldr op@ [] (List.map (fn(_,args)=>args) code)
                in
                   (* List.map (fn(nSize,args)=> Dst.E_Op(DstOp.sumVec([nSize],nSize),args)) code*)
                 [Dst.E_Op(DstOp.sumVec(pieces,oSize),args)]


                end
            | _ => let
                val code=createOps (pieces, 0,indexAt, [])
                in
                    List.map (fn(nSize,args)=> Dst.E_Op(rator nSize,args)) code
                end
            (*end case*))
        end

    (* Same funciton as above
    *Except this first scans for special case ProjectTensor LowIL Op.
    *ProjectTensor is an op that slices a vector from a higher order tensor
    * That vec could be in pieces
    * So we load each one and the next step wraps a mux around it
    * We can assume the higher order tensor is an array
    * This rewrites the PorjectTensor op as an E_LoadArr.
    *Otherwise hand off to above function 
    *)
    fun mkOps(isFill,lhsKind,oldrator,rator,oSize,pieces,argScas,argVecs,indexAt)=  (case (oldrator,pieces,argVecs)
        of (SrcOp.ProjectTensor(_,_,indTy,argTy),_,[a]) => let
            val A=isAlignedLoad(isFill,argTy)
            val shift=(case (indTy,argTy)
                of (Ty.indexTy[i],Ty.TensorTy[_,argTyX])=> i*argTyX
                    | (Ty.indexTy[j,i],Ty.TensorTy[_,argTyY,argTyX])=> j*(argTyX*argTyY)+i*argTyX
                    |  _ =>raise Fail "Project Tensor of a unhandled size"
                    (*end case *))
            fun mkLoad ([], _, code) = code
            | mkLoad (nSize::es, offset, code)=
                mkLoad (es, offset + IntInf.fromInt nSize,
                code@[Dst.E_LoadArr(A, nSize,oSize,a, Dst.E_Lit(Literal.Int offset))])
            in
                mkLoad (pieces, IntInf.fromInt shift, [])
            end
        | (SrcOp.sumVec _,[nSize],[a]) =>  [Dst.E_Op(DstOp.sumVec([nSize],oSize), [getArg(isFill,lhsKind,a,0, nSize, oSize, 0)])]
        | _ => mkGenericOps(isFill,lhsKind,oldrator,rator,oSize,pieces,argScas,argVecs,indexAt)
        (*end case*))

        (**************************************)
    (*vecToTree:TreeIL.Var.kind*LowILOP*TreeILOP*int*int*int list*TreeILExp list *TreeILExp list *bool->TreeILExp List
    *Main function that turns a low-il vector operation into tree-il stmt 
    *)
    fun vecToTree(lhs,origrator,rator,nSize,oSize,pieces,argScas,argVecs,isFill)= let
        val splitTy=DstTy.vectorLength pieces
        val aligned= isAlignedStore(isFill,length pieces)
        val indexAt=IntInf.fromInt 0
        (*Create Ld Expressions and Tree Ops*)
        val lhsKind=DstV.kind lhs

        val ops=mkOps(isFill,lhsKind,origrator,rator,oSize,pieces,argScas,argVecs,indexAt)
    in
        mkStmt(lhs,lhsKind,origrator,isFill,oSize,aligned,splitTy,ops)
    end

    (* consVecToTree:int*int*int list*TreeIL.Exp* bool->TreeIL.Exp
     * Takes Cons of a vector and returns TreeIL.exp inside E_Mux.
     *  When isFill is true, creates zeros
     *)
    fun consVecToTree(_,oSize,[nSize],args,true)= let
        val nArg=length(args)
        val n=nSize-nArg
        val newArgs=List.tabulate(n, (fn _=>Dst.E_Lit(Literal.Int 0)))
        val op1=Dst.E_Cons(nSize, oSize,args@newArgs)
        val aligned= isAlignedStore(true,1)
        val splitTy=DstTy.vectorLength [nSize]
        in
            Dst.E_Mux(aligned,true,oSize,splitTy,[op1])
        end
    | consVecToTree(_,_,_,_,true)= raise Fail"In ConsVecToTree-isFill with more than 1 piece"
    | consVecToTree(nSize,oSize,pieces,args,isFill)= let
        val aligned= isAlignedStore(isFill,length pieces)
        val splitTy=DstTy.vectorLength pieces
        fun createOps ([], _,_,_) = []
        | createOps (nSize::es, offset,arg, code)=
            [Dst.E_Cons(nSize, nSize,List.take(arg,nSize))]@
            createOps (es, offset + IntInf.fromInt nSize, List.drop(arg,nSize),code)
        val ops= createOps (pieces, 0,args, [])
        in
            Dst.E_Mux(aligned,isFill,oSize,splitTy,ops)
        end
        (**************************************)

    (*Low-IL operators to Tree-IL operators*)
    fun expandOp rator=(case rator
        of SrcOp.IAdd  =>    DstOp.IAdd
        | SrcOp.ISub  =>    DstOp.ISub
        | SrcOp.IMul  =>    DstOp.IMul
        | SrcOp.IDiv  =>    DstOp.IDiv
        | SrcOp.INeg  =>    DstOp.INeg
        | SrcOp.Abs ty =>    DstOp.Abs ty
        | SrcOp.LT ty =>    DstOp.LT  ty
        | SrcOp.LTE ty =>    DstOp.LTE  ty
        | SrcOp.EQ ty =>    DstOp.EQ  ty
        | SrcOp.NEQ ty =>    DstOp.NEQ  ty
        | SrcOp.GT ty =>    DstOp.GT  ty
        | SrcOp.GTE ty =>    DstOp.GTE  ty
        | SrcOp.Not =>    DstOp.Not
        | SrcOp.Max =>    DstOp.Max
        | SrcOp.Min =>    DstOp.Min
        | SrcOp.Clamp ty =>    DstOp.Clamp ty
        | SrcOp.Lerp ty =>    DstOp.Lerp  ty
        | SrcOp.Sqrt=>      DstOp.Sqrt
      | SrcOp.Cosine=>      DstOp.Cosine
      | SrcOp.ArcCosine=>      DstOp.ArcCosine
      | SrcOp.Sine=>      DstOp.Sine
        | SrcOp.Zero ty =>    DstOp.Zero  ty
        | SrcOp.PrincipleEvec ty =>    DstOp.PrincipleEvec ty
        | SrcOp.EigenVals2x2 =>    DstOp.EigenVals2x2
        | SrcOp.EigenVals3x3 =>    DstOp.EigenVals3x3
        | SrcOp.EigenVecs2x2 =>    DstOp.EigenVecs2x2
        | SrcOp.EigenVecs3x3 =>    DstOp.EigenVecs3x3
        | SrcOp.Select(ty as SrcTy.TupleTy tys, i)  =>    DstOp.Select( ty, i)
        | SrcOp.Index (ty, i ) =>    DstOp.Index ( ty, i)
        | SrcOp.Subscript ty =>    DstOp.Subscript  ty
        | SrcOp.Ceiling d =>    DstOp.Ceiling d
        | SrcOp.Floor d =>    DstOp.Floor d
        | SrcOp.Round d =>    DstOp.Round d
        | SrcOp.Trunc d =>    DstOp.Trunc d
        | SrcOp.IntToReal =>    DstOp.IntToReal
	| SrcOp.R r => DstOp.R r 
        | SrcOp.RealToInt d =>    DstOp.RealToInt d
        (*| SrcOp.VoxelAddress( info, offset)  => expandVoxelAddress  (y, info, offset, args')
        | SrcOp.LoadVoxels (rty, d ) =>    DstOp.LoadVoxels( rty, d)*)
        (*Maybe should delete?*)
        (*  | SrcOp.LoadImage info =>    DstOp.LoadImage info*)
        | SrcOp.Inside info =>    DstOp.Inside info
        | SrcOp.Translate V=>  DstOp.Translate V
        | SrcOp.addSca =>DstOp.addSca
        | SrcOp.subSca => DstOp.subSca
        | SrcOp.prodSca => DstOp.prodSca
        | SrcOp.divSca => DstOp.divSca
	| SrcOp.powRat ty => raise Fail"PowRat"
	| SrcOp.powInt => raise Fail"PowInt"
        (*| SrcOp.Norm ty =>  (DstOp.Norm ty)*)
        | SrcOp.Normalize d =>(DstOp.Normalize d)
        | SrcOp.imgAddr(v,indexAt, dim)=>DstOp.imgAddr(v, indexAt, dim)
        | SrcOp.baseAddr V => DstOp.baseAddr V
        (*EigenVecs,mkDynamic, Append,Prepend, Concat,Length,ImageAddress,LoadVoxel,Inputs, and Pritns*)
        (*| SrcOp.Input e=>*)
	| SrcOp.LoadImage args => DstOp.LoadImage args
	| SrcOp.Input inp => DstOp.Input inp
	| SrcOp.Print tys => DstOp.Print tys
        | rator => raise Fail ("bogus operator " ^ SrcOp.toString rator)
      (* end case *))
    end

  end

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