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

SCM Repository

[diderot] View of /branches/charisee/src/compiler/mid-to-low/ein-to-low.sml
ViewVC logotype

View of /branches/charisee/src/compiler/mid-to-low/ein-to-low.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3174 - (download) (annotate)
Mon Mar 30 11:46:58 2015 UTC (3 years, 11 months ago) by cchiw
File size: 10260 byte(s)
hack
(*
* genfn-Does preliminary scan of the body of EIN.EIN for vectorization potential
* If there is a field then passes to FieldToLow
* If there is a tensor then passes to handle*() functions to check if indices match
* i.e. <A_ij+B_ij>_ij vs.<A_ji+B_ij>_ij
*
*     (1) If indices match then passes to Iter->VecToLow functions.
*            Creates LowIL vector operators.
*     (2) Iter->ScaToLow
*           Creates Low-IL scalar operators
* Note. The Iter function creates LowIL.CONS and therefore binds the indices in the EIN.body 
*)
structure EinToLow = struct
    local

    structure Var = LowIL.Var
    structure E = Ein
    structure P=Printer
    structure Iter=Iter
    structure EtoFld= FieldToLow
    structure EtoSca= ScaToLow
    structure EtoVec= VecToLow
    structure H=Helper

    in

    fun iter e=Iter.prodIter e
    fun evalField e= EtoFld.evalField e
    fun intToReal n=H.intToReal n
    
    fun testp p=print(String.concat p)
    
    (*dropIndex: a list-> int*a*alist
    * alpha::i->returns  length of list-1,i,alpha
    *)
    fun dropIndex alpha=let
        val (e1::es)=List.rev(alpha)
        in (length alpha-1,e1,List.rev es)
        end

    (*matchLast:E.alpha*int -> (E.alpha) Option
    * Is the last index of alpha E.V n.
    * If so, return the rest of the list 
    *)
    fun matchLast(alpha, n)=let
        val (e1::es)=List.rev(alpha)
        in (case e1
            of E.V v =>(case (n=v)
                of true => SOME(List.rev es)
                |_ =>   NONE
                (*end case*))
            | _ => NONE
            (*end case*))
        end

    (*matchFindLast:E.alpha *int -> E.alpha option* E.mu option
    * Is the last index of alpha =n.
    * is n anywhere else?
    *)
    fun matchFindLast(alpha, n)=let
        val es=List.tl(List.rev(alpha))
        val f=List.find(fn E.V e=>e=n|_=>false) es
        in
            (matchLast(alpha,n),f)
        end 

    (*runGeneralCase:Var*E.EIN*Var-> Var*LowIL.ASSN list
    * does not do vector projections
    * instead approach like a general EIN
    *)
    fun runGeneralCase info=let
        val (lhs,e,args)=info
        val index=Ein.index e
        in
            iter(index,index,EtoSca.generalfn,info)
        end

    (*handleNeg:.body* int list*info ->Var*LowIL.ASSN list
    * info:(string*E.EIN*Var list)
    * low-IL code for scaling a vector with negative 1.
    *)
    fun handleNeg(E.Neg(E.Tensor(id ,alpha)),index,info)=let
        val (n,vecIndex,index')=dropIndex index
        in (case (matchLast(alpha,n))
            of SOME ix1 => let
                val (vA,A)= intToReal ~1
                val (lhs,e,args)=info
                val nextfnargs=(lhs,Ein.params e,args,vecIndex, vA, id,ix1)
                val (vB,B)=iter(index,index',EtoVec.negV,nextfnargs)
                in
                    (vB,A@B)
                end
            | NONE => runGeneralCase info
            (*end case*))
        end

    (*handleSub:E.body*int list*info ->Var*LowIL.ASSN list
    * info:(string*E.EIN*Var list)
    * low-IL code for subtracting two vectors
    *)
    fun handleSub(E.Sub(E.Tensor(id1,alpha),E.Tensor(id2,beta)),index,info)=let
        val (n,vecIndex,index')=dropIndex index
        in (case(matchLast(alpha,n) , matchLast(beta,n)) of
            (SOME ix1,SOME ix2)=>let
                val (lhs,e,args)=info
    
                val nextfnargs=(lhs,Ein.params e, args,vecIndex,id1,ix1,id2,ix2)
                in
                    iter(index,index',EtoVec.subV,nextfnargs)
                end 
            | _   => runGeneralCase info
            (*end case*))
        end

    (*handleAdd:E.body*int list*info ->Var*LowIL.ASSN list
    * info:(string*E.EIN*Var list)
    * low-IL code for adding two vectors
    *)
    fun handleAdd(E.Add es,index,info)=let
        val (n,vecIndex,index')=dropIndex index
        (*check that each tensor in addition list has matching indices*)
        fun sample([],rest)=let
            val (lhs,e,args)=info
            val nextfnargs=(lhs,Ein.params e, args,vecIndex,rest)
            in
                iter(index,index',EtoVec.addV,nextfnargs)
            end 
        | sample(E.Tensor(id,alpha)::ts,rest) =(case (matchLast(alpha,n))
            of SOME ix1    => sample(ts,rest@[(id,ix1)])
            | _            => runGeneralCase info
            (*end case*))
        | sample _ = runGeneralCase info
        in
            sample(es,[])
        end

    (*handleScale:E.tensor_id*E.tensor_id*E.alpha*int list*info ->Var*LowIL.ASSN list
    * info:(string*E.EIN*Var list)
    * low-IL code for adding scaling a vector
    *)
    fun handleScale(id1,id2,alpha2,index,info)=let
        val (n,vecIndex,index')=dropIndex index
        in (case matchLast(alpha2,n)
            of SOME ix2=>  let
                val (lhs,e,args)=info
                val nextfnargs=(lhs,Ein.params e, args,vecIndex,id1,[],id2,ix2)
                in
                    iter(index,index',EtoVec.scaleV,nextfnargs)
                end
            | _=>runGeneralCase info
            (*end case*))
        end

    (*handleProd:E.body*int list*info ->Var*LowIL.ASSN list
    * info:(string*E.EIN*Var list)
    * low-IL code for vector product
    *)
    fun handleProd(E.Prod[E.Tensor(id1 , alpha), E.Tensor(id2, beta)],index,info)=let
        val (lhs,e,args)=info
        val (n,vecIndex,index')=dropIndex index
        in (case(matchFindLast(alpha,n),matchFindLast(beta,n))
            of ((SOME ix1,NONE),(SOME ix2,NONE)) => let
                (*n is the last index of alpha, beta and nowhere else,possible modulate*)
                val nextfnargs=(lhs,Ein.params e, args,vecIndex,id1,ix1,id2,ix2)
                in
                    iter(index,index',EtoVec.prodV,nextfnargs)
                end
            | ((NONE,NONE),(SOME ix2,NONE)) =>let
                (*n is the last index of beta and nowhere else,possible scaleVector*)
                val nextfnargs=(lhs,Ein.params e, args,vecIndex,id1,alpha,id2,ix2)
                in
                    iter(index,index',EtoVec.scaleV,nextfnargs)
                end
            | ((SOME ix1,NONE),(NONE,NONE)) =>let
                (*n is the last index of alpha and nowhere else,ossile scaleVector*)
                val nextfnargs=(lhs,Ein.params e, args,vecIndex,id2,beta,id1,ix1)
                in
                    iter(index,index',EtoVec.scaleV,nextfnargs)
                end
            | _ =>runGeneralCase info
            (*end case*))
        end
    
    (*handleSumProd:E.body*int list*info ->Var*LowIL.ASSN list
    * info:(string*E.EIN*Var list)
    * low-IL code for dot product
    *)
    fun handleSumProd1(E.Sum([(E.V v,_,ub)],E.Prod[E.Tensor(id1 , alpha), E.Tensor(id2, beta)]),index,info)=(case(matchFindLast(alpha,v),matchFindLast(beta,v))
            of ((SOME ix1,NONE),(SOME ix2,NONE)) => let
                (*v is the last index of alpha, beta and nowhere else,possible sumProd*)
                val (lhs,e,args)=info
                val nextfnargs=(lhs,Ein.params e, args,ub+1,id1,ix1,id2,ix2)
                in
                    iter(index,index,EtoVec.dotV,nextfnargs)
                end
            | _ =>runGeneralCase info
        (*end case*))
    
    (*handleSumProd:E.body*int list*info ->Var*LowIL.ASSN list
    * info:(string*E.EIN*Var list)
    * low-IL code for double dot product
    * Sigma_{i,j} A_ij B_ij
    *)
    fun handleSumProd2(E.Sum([(E.V v1,lb1,ub1),(E.V v2,lb2,ub2)],E.Prod[E.Tensor(id1 , alpha), E.Tensor(id2, beta)]),index,info)=let
            fun check(v,ub,sx)=(case(matchFindLast(alpha,v),matchFindLast(beta,v))
                of ((SOME ix1,NONE),(SOME ix2,NONE)) => let
                    (*v is the last index of alpha, beta and nowhere else,possible sumProd*)
                    val (lhs,e,args)=info
                    val nextfnargs=(lhs,Ein.params e, args,sx,ub+1,id1,ix1,id2,ix2)
                    in
                        SOME(iter(index,index,EtoVec.sumDotV,nextfnargs))
                    end
                | _=> NONE
                (*end case*))
            in (case check(v1,ub1,(E.V v2,lb2,ub2))
                of SOME e=>e
                | _=> (case check(v2,ub2,(E.V v1,lb1,ub1))
                    of SOME e=> e
                    |_ =>runGeneralCase info
                    (*end case*))
                (*end case*))
            end
    
    (*scan:var*E.Ein*Var list * Var list-> Var*LowIL.Assgn list
    *scans body  for vectorization potential
    *)
    fun scan(y,e,args)= let
        val lhs=LowIL.Var.name y
        val b=Ein.body e
        val index=Ein.index e
        val info=(lhs,e,args)
        val all=(b,index,info)
        fun gen body=(case (index,body)
            of (_::es,E.Neg(E.Tensor(_ ,i::ix)))                          =>
                handleNeg all
            |  (_::es,E.Sub(E.Tensor(_,i::ix),E.Tensor(_,j::jx)))           =>
                handleSub all
            |  (_::es, E.Add(E.Tensor(_,i::ix)::_))                         =>
                handleAdd all
            | (_::es, E.Prod[E.Tensor(s, []), E.Tensor(v, j::jx)])         =>
                    handleScale(s,v,j::jx,index,info)
            |  (_::es,E.Prod[E.Tensor(v, j::jx), E.Tensor(s , [])])         =>
                handleScale(s,v,j::jx,index,info)
            |  (_::es,E.Prod[E.Tensor(_ , i::ix), E.Tensor(_, j::jx)])        =>
                handleProd all
            |  ( _,E.Sum([_], E.Prod[E.Tensor(_ , i::ix), E.Tensor(_, j::jx)])) =>
                handleSumProd1 all
            |  ( _ ,E.Sum([_,_], E.Prod[E.Tensor(_ , i::ix), E.Tensor(_, j::jx)])) =>
                handleSumProd2 all
            |  ( _ ,E.Sum(x,E.Prod(E.Img(Vid,_,_)::E.Krn(Hid,_,_)::_)))    =>
                (
                iter(index,index,evalField,(body,info)))
            |  (_,_ )=> runGeneralCase info
            (*end case*))
       
        val (_,code) =gen b

        in (case code
            of(* []=> []
            | *) _=> let (*need to reassign the last assgn*)
                val LowIL.ASSGN (a1,A)=List.hd(List.rev(code))
                val c=LowIL.ASSGN (y,A)
                in
                    code@[c]
                end
            (*end case*))
        end 
            



end (* local *)

end

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