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/evalKrn.sml
ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2525 - (download) (annotate)
Tue Jan 21 19:14:22 2014 UTC (5 years, 6 months ago) by cchiw
File size: 5418 byte(s)
eintypes->mid-iltypes
(* Split Functions before code generation process*)
structure evalKrn = struct
    local
    structure E = Ein
  
    structure DstIL = LowIL
    structure DstTy = LowILTypes
    structure DstOp = LowOps

    structure P=Printer
     structure Var = LowIL.Var
 structure SrcIL = MidIL
 structure SrcOp = MidOps
 structure SrcSV = SrcIL.StateVar
 structure SrcTy = MidILTypes
 structure VTbl = SrcIL.Var.Tbl
  structure g=genHelper
 
 
    in
 

 
 

 fun createProdVec(vA,vB,dim)=g.aaV( DstOp.prodVec(dim),[vA,vB],"prodVec",DstTy.TensorTy([dim]))
 fun createAddVec(vA,vB,dim)=g.aaV(DstOp.addVec(dim),[vA,vB],"AddVec",DstTy.TensorTy([dim]))
 
 
 
fun iadd (r : DstIL.var, a, b) = (r, DstIL.OP(DstOp.IAdd, [a, b]))
fun ilit (r : DstIL.var, n) = (r, DstIL.LIT(Literal.Int(IntInf.fromInt n)))
fun ilit (r : DstIL.var, n) = (r, DstIL.LIT(Literal.Int(IntInf.fromInt n)))
fun imul (r : DstIL.var, a, b) = (r, DstIL.OP(DstOp.IMul, [a, b]))

 (* convert a rational to a FloatLit.float value.  We do this by long division
 * with a cutoff when we get to 12 digits.
 *)
 
 fun ratToFloat r = (case Rational.explode r
 of {sign=0, ...} => FloatLit.zero false
 | {sign, num, denom=1} => FloatLit.fromInt(IntInf.fromInt sign * num)
 | {sign, num, denom} => let
 (* normalize so that num <= denom *)
 val (denom, exp) = let
 fun lp (n, denom) = if (denom < num)
 then lp(n+1, denom*10)
 else (denom, n)
 in
 lp (1, denom)
 end
 (* normalize so that num <= denom < 10*num *)
 val (num, exp) = let
 fun lp (n, num) = if (10*num < denom)
 then lp(n-1, 10*num)
 else (num, n)
 in
 lp (exp, num)
 end
 (* divide num/denom, computing the resulting digits *)
 fun divLp (n, a) = let
 val (q, r) = IntInf.divMod(a, denom)
 in
 if (r = 0) then (q, [])
 else if (n < 12) then let
 val (d, dd) = divLp(n+1, 10*r)
 in
 if (d < 10)
 then (q, (IntInf.toInt d)::dd)
 else (q+1, 0::dd)
 end
 else if (IntInf.div(10*r, denom) < 5)
 then (q, [])
 else (q+1, []) (* round up *)
 end
 val digits = let
 val (d, dd) = divLp (0, num)
 in
 (IntInf.toInt d)::dd
 end
 in
 FloatLit.fromDigits{isNeg=(sign < 0), digits=digits, exp=exp}
 end
 (* end case *))
 
 
(* expand the EvalKernel operations into vector operations.  The parameters
* are
*	result	-- the lhs variable to store the result
*	d	-- the vector width of the operation, which should be equal
*		   to twice the support of the kernel
*	h	-- the kernel
*	k	-- the derivative of the kernel to evaluate
*
* The generated code is computing
*
*	result = a_0 + x*(a_1 + x*(a_2 + ... x*a_n) ... )
*
* as a d-wide vector operation, where n is the degree of the kth derivative
* of h and the a_i are coefficient vectors that have an element for each
* piece of h.  The computation is implemented as follows
*
*	m_n	= x * a_n
*	s_{n-1}	= a_{n-1} + m_n
*	m_{n-1}	= x * s_{n-1}
*	s_{n-2}	= a_{n-2} + m_{n-1}
*	m_{n-2}	= x * s_{n-2}
*	...
*	s_1	= a_1 + m_2
*	m_1	= x * s_1
*	result	= a_0 + m_1
*
* Note that the coeffient vectors are flipped (cf high-to-low/probe.sml).
*)

 (* >*)
     
     (*   Polynomial:3, length of position is 2.
     
     a_0=[d0,e0]
     a_1=[d_1,e_1]
     a_2=[d_1,e_1]
     -----------------------
     
     [d0e0],[d1e1],[d2e2]
     result=a_0 +x(a_1+x a_2)
      
    
     --OtherwiseWise need to flip
     
      [d0,d1,d2],[e0,e1,e2]=>  [d0e0],[d1e1],[d2e2]
     result=a_0 +x(a_1+ x a_2)
     
     
*)
     



     
fun expandEvalKernel (d, h, k, x,axis) = let
     
      val tetser=print "\n\n ######  In eval kernel  ########  \n\n "
     
     val {isCont, segs} = Kernel.curve (h, k)
     (* degree of polynomial *)
     val deg = List.length(hd segs) - 1
     val dd=List.length(hd segs)
     
     val ss=Kernel.support(h)
        (*segs is length 2*support, inner list is listof poynomial*)
     val m=print(String.concat["Axis: ", Int.toString(axis)," Length of segs:",Int.toString(length(segs))," segs next",Int.toString(dd)," k:", Int.toString(k),"SUpport:",Int.toString(ss)])
     
     val segs = Vector.fromList (List.rev (List.map Vector.fromList segs))
      fun coefficient d i =
         Literal.Float(ratToFloat (Vector.sub (Vector.sub(segs, i), d)))

     
      val ty = DstTy.vecTy d
        val coeffs = List.tabulate (deg+1,fn i => DstIL.Var.new("P"^Int.toString i, ty))
     
     
     (* code to define the coefficient vectors *)
     val coeffVecs = let
        fun mk (x, (i, code)) = let
                val lits = List.tabulate(d, coefficient i)
                val vars = List.tabulate(d, fn _ => DstIL.Var.new("_f", DstTy.realTy))
                val code =
                    ListPair.map (fn (x, lit) => (x, DstIL.LIT lit)) (vars, lits) @(x, DstIL.CONS(DstIL.Var.ty x, vars)) :: code
                in
                    (i-1, code)
                end
        in
            #2 (List.foldr mk (deg, []) coeffs)
        end
     
     val q=List.map (fn(x,y)=>DstIL.ASSGN (x,y)) coeffVecs
     val tester= List.map genHelper.printX q
     
 
     fun m([e2,e1],code)=let
            val (vA,A)= createProdVec(x,e2,d)
            val (vB,B)=createAddVec(e1,vA,d)
            in
                (vB,code@A@B)
            end
        | m (e2::e1::es,code)= let
            val (vA,A)= createProdVec(x,e2,d)
            val (vB,B)=createAddVec(e1,vA,d)
            in
                m(vB::es,code@A@B)
            end
     val (vC,code')= m(List.rev coeffs, [])
  



     
     in
        (vC,q@code')
    end



end (* local *)

end 

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