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

SCM Repository

[diderot] View of /branches/vis15/src/compiler/translate/translate-basis.sml
ViewVC logotype

View of /branches/vis15/src/compiler/translate/translate-basis.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4043 - (download) (annotate)
Sun Jun 26 14:00:38 2016 UTC (3 years, 2 months ago) by jhr
File size: 32388 byte(s)
  Working on merge: changed the way that we handle kernels in the AST and SimpleAST IRs (treat
  them like literals, instead of like variables).  Added code to rewrite Inside tests in Simple
  IR to use the image instead of the field, which fixes a problem with trying to do inside tests
  on Ein fields.  Added code to promote locals to globals as part of the simplify-vars phase.
(* translate-basis.sml
 *
 * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
 *
 * COPYRIGHT (c) 2015 The University of Chicago
 * All rights reserved.
 *
 * Translation for basis operations in Simple AST to HighIR code
 *)

structure TranslateBasis : sig

  (* translate(lhs, f, mvs, args) translates the application of f (specialized
   * to the instantiated meta variables mvs) to a list of SSA assignments in
   * reverse order.
   *)
    val translate : (HighIR.var * Var.t * SimpleTypes.meta_arg list * HighIR.var list)
          -> HighIR.assignment list

  end = struct

    structure BV = BasisVars
    structure IR = HighIR
    structure DstTy = HighTypes
    structure Op = HighOps
    structure Ty = SimpleTypes
    structure VTbl = Var.Tbl
    structure Mk = MkOperators

    fun trType (Ty.TY ty) = TranslateTy.tr ty
      | trType _ = raise Fail "expected type"
    fun dimVarToInt (Ty.DIM d) = d
      | dimVarToInt _ = raise Fail "expected dim"
    fun dimVarToTensor dv = DstTy.tensorTy[dimVarToInt dv]
    fun dimVarToMatrix dv = let
          val d = dimVarToInt dv
          in
            DstTy.tensorTy[d, d]        (* square matrix type *)
          end
    fun shapeVarToTensor (Ty.SHAPE shp) = DstTy.tensorTy shp
      | shapeVarToTensor _ = raise Fail "expected shape"

    fun assign (y, rator, xs) = [IR.ASSGN(y, IR.OP(rator, xs))]

    fun simpleOp rator (y, [], xs) = assign (y, rator, xs)

    fun tensorOp rator (y, [sv], xs) = assign (y, rator(shapeVarToTensor sv), xs)

    fun vectorOp rator (y, [dv], xs) = assign (y, rator(dimVarToTensor dv), xs)

  (* utility functions for synthesizing eigenvector/eigenvalue code *)
    fun eigenVec (rator, dim) = let
          val ty = DstTy.SeqTy(DstTy.realTy, SOME dim)
          in
            fn (y, _, [m]) => let
                val v = IR.Var.new("evals", ty)
                in
                  [IR.MASSGN([v, y], rator, [m])]
                end
          end
    fun eigenVal (rator, dim) = let
          val ty = DstTy.SeqTy(DstTy.vecTy dim, SOME dim)
          in
            fn (y, _, [m]) => let
                val v = IR.Var.new("evecs", ty)
                in
                  [IR.MASSGN([y, v], rator, [m])]
                end
          end

    fun assignEin (y, rator, xs) = IR.ASSGN(y, IR.EINAPP(rator, xs))

    fun simpleEOp rator (y, _, xs) = [assignEin(y, rator, xs)]

    fun dist (y, d, xs) = let
          val t0 = IR.Var.new("t0", DstTy.TensorTy[d])
          in [
            assignEin(t0, Mk.subTT[d], xs),
            assignEin(y, Mk.normT[d], [t0])]
          end

  (* build a table that maps Basis variables to their translation functions *)
    val tbl : ((IR.var * Ty.meta_arg list * IR.var list) -> IR.assignment list) VTbl.hash_table = let
          val tbl = VTbl.mkTable (128, Fail "Translate table")
          fun insert (id, def) = (case VTbl.find tbl id
                 of NONE => VTbl.insert tbl (id, def)
                  | SOME _ => raise Fail("duplicate definition of " ^ Var.nameOf id)
                (* end case *))
          in
            List.app insert [
                (BV.lt_ii,              simpleOp(Op.LT DstTy.IntTy)),
                (BV.lt_rr,              simpleOp(Op.LT DstTy.realTy)),
                (BV.lte_ii,             simpleOp(Op.LTE DstTy.IntTy)),
                (BV.lte_rr,             simpleOp(Op.LTE DstTy.realTy)),
                (BV.gte_ii,             simpleOp(Op.GTE DstTy.IntTy)),
                (BV.gte_rr,             simpleOp(Op.GTE(DstTy.realTy))),
                (BV.gt_ii,              simpleOp(Op.GT DstTy.IntTy)),
                (BV.gt_rr,              simpleOp(Op.GT(DstTy.realTy))),
                (BV.equ_bb,             simpleOp(Op.EQ DstTy.BoolTy)),
                (BV.equ_ii,             simpleOp(Op.EQ DstTy.IntTy)),
                (BV.equ_ss,             simpleOp(Op.EQ DstTy.StringTy)),
                (BV.equ_rr,             simpleOp(Op.EQ(DstTy.realTy))),
                (BV.neq_bb,             simpleOp(Op.NEQ DstTy.BoolTy)),
                (BV.neq_ii,             simpleOp(Op.NEQ DstTy.IntTy)),
                (BV.neq_ss,             simpleOp(Op.NEQ DstTy.StringTy)),
                (BV.neq_rr,             simpleOp(Op.NEQ(DstTy.realTy))),
                (BV.add_ii,             simpleOp Op.IAdd),
                (BV.sub_ii,             simpleOp Op.ISub),
                (BV.mul_ii,             simpleOp Op.IMul),
                (BV.div_ii,             simpleOp Op.IDiv),
                (BV.op_mod,             simpleOp Op.IMod),
                (BV.neg_i,              simpleOp Op.INeg),
                (BV.add_tt,             fn (y, [shp], xs) => let
                                          val ty1 as DstTy.TensorTy dd1 = shapeVarToTensor shp
                                          val rator = Mk.addTT(dd1)
                                          in
                                            [assignEin(y, rator, xs)]
                                          end),
                (BV.add_ff,             fn (y, [_, Ty.DIM d, Ty.SHAPE dd], xs) =>
                                          [assignEin(y, Mk.addFF(d, dd), xs)]),
                (BV.add_ft,             fn (y, [_, Ty.DIM d, Ty.SHAPE dd], [f, s]) =>
                                          [assignEin(y, Mk.addTF(d, dd), [s, f])]),
                (BV.add_tf,             fn (y, [_, Ty.DIM d, Ty.SHAPE dd], xs) =>
                                          [assignEin(y, Mk.addTF(d, dd), xs)]),
                (BV.sub_tt,             fn (y, [shp], xs) => let
                                          val ty1 as DstTy.TensorTy dd1 = shapeVarToTensor shp
                                          val rator = Mk.subTT dd1
                                          in
                                            [assignEin(y, rator, xs)]
                                          end),
                (BV.sub_ff,             fn (y, [_, Ty.DIM d, Ty.SHAPE dd], xs) =>
                                          [assignEin(y, Mk.subFF(d, dd), xs)]),
                (BV.sub_ft,             fn (y, [_, Ty.DIM d, Ty.SHAPE dd], [x1, x2]) =>
                                          [assignEin(y, Mk.subFT(d, dd), [x2, x1])]),
                (BV.sub_tf,             fn (y, [_, Ty.DIM d, Ty.SHAPE dd], xs) =>
                                          [assignEin(y, Mk.subTF(d, dd), xs)]),
                (BV.mul_rr,             fn (y, _, args) => [assignEin(y, Mk.mulRR, args)]),
                (BV.mul_rt,             fn (y, [shp], xs) => let
                                          val ty1 as DstTy.TensorTy dd1 = shapeVarToTensor shp
                                          val rator = Mk.mulRT(dd1)
                                          in
                                            [assignEin(y, rator, xs)]
                                          end),
                (BV.mul_tr,             fn (y, [shp], [t, r]) => let
                                          val ty1 as DstTy.TensorTy dd1 = shapeVarToTensor shp
                                          val rator = Mk.mulRT dd1
                                          in
                                            [assignEin(y, rator, [r, t])]
                                          end),
                (BV.mul_rf,             fn (y, [_, Ty.DIM d, Ty.SHAPE dd], xs) =>
                                          [assignEin(y, Mk.mulRF(d, dd), xs)]),
                (BV.mul_fr,             fn (y, [_, Ty.DIM d, Ty.SHAPE dd], [f, s]) =>
                                          [assignEin(y, Mk.mulRF(d, dd), [s, f])]),
                (BV.mul_ss,             fn (y, [_, Ty.DIM d], xs) =>
                                          [assignEin(y, Mk.mulSS d, xs)]),
                (BV.mul_sf,             fn (y, [_, Ty.DIM d, Ty.SHAPE dd], xs) =>
                                          [assignEin(y, Mk.mulSF(d, dd), xs)]),
                (BV.mul_fs,             fn (y, [_, Ty.DIM d, Ty.SHAPE dd], [s, f]) =>
                                          [assignEin(y, Mk.mulSF(d, dd), [f, s])]),
                (BV.mul_st,             fn (y, [_, Ty.DIM d, Ty.SHAPE dd], xs) =>
                                          [assignEin(y, Mk.mulST(d, dd), List.rev xs)]),
                (BV.mul_ts,             fn (y, [_, Ty.DIM d, Ty.SHAPE dd], xs) =>
                                          [assignEin(y, Mk.mulST(d, dd), xs)]),
                (BV.div_rr,             fn (y, _, args) => [assignEin(y, Mk.divRR, args)]),
                (BV.div_tr,             fn (y, [shp], xs) => let
                                          val ty1 as DstTy.TensorTy dd1 = shapeVarToTensor shp
                                          val rator = Mk.divTR dd1
                                          in
                                            [assignEin(y, rator, xs)]
                                          end),
                (BV.div_fr,             fn (y, [_, Ty.DIM d, Ty.SHAPE dd], xs) =>
                                          [assignEin(y, Mk.divFR(d, dd), xs)]),
                (BV.div_fs,             fn (y, [_, _, Ty.DIM d, Ty.SHAPE dd], xs) =>
                                          [assignEin(y, Mk.divFS(d, dd), xs)]),
                (BV.div_ss,             fn (y, [_, Ty.DIM d], xs) =>
                                          [assignEin(y, Mk.divSS d, xs)]),
                (BV.div_ts,             fn (y, [_,Ty.DIM d, Ty.SHAPE dd], xs) =>
                                          [assignEin(y, Mk.divTS(d, dd), xs)]),
                (BV.pow_ri,             simpleOp Op.Power),
                (BV.pow_rr,             fn (y, _, args) => assign(y, Op.MathFn MathFns.POW, args)),
                (BV.pow_si,             fn (y, [_, Ty.DIM d1], [f, n]) => let
                                          fun getN x  = (case IR.Var.getDef x
                                                 of IR.LIT(Literal.Int n) => IntInf.toInt n
                                                  | _ => raise Fail "impossible"
                                                (* end case *))
                                          in
                                            [assignEin(y, Mk.powFI(d1, getN n), [f])]
                                          end),
                (BV.curl2D,             simpleEOp Mk.curl2d),
                (BV.curl3D,             simpleEOp Mk.curl3d),
                (BV.convolve_vk,        fn (y, [_, Ty.DIM d, Ty.SHAPE dd], xs) =>
                                          [assignEin(y, Mk.conv(d, dd), xs)]),
                (BV.convolve_kv,        fn (y, [_, Ty.DIM d, Ty.SHAPE dd], [k, v]) =>
                                          [assignEin(y, Mk.conv(d, dd), [v, k])]),
                (BV.neg_t,              fn (y, [shp], xs) => let
                                          val ty1 as DstTy.TensorTy dd1 = shapeVarToTensor shp
                                          val rator = Mk.negTT dd1
                                          in
                                            [assignEin(y, rator, xs)]
                                          end),
                (BV.neg_f,              fn (y, [_, Ty.DIM d, Ty.SHAPE dd], xs) =>
                                          [assignEin(y, Mk.negFF(d, dd), xs)]),
                (BV.op_probe,           fn (y, [_, Ty.DIM d, Ty.SHAPE dd], xs) =>
                                          [assignEin(y, (Mk.probe(dd, d)), xs)]),
                (BV.op_D,               fn (y, [_, Ty.DIM d], xs) =>
                                          if (d = 2) orelse (d = 3)
                                            then [assignEin(y, Mk.grad [d], xs)]
                                            else raise Fail "unsupported gradient"),
                (BV.op_Dotimes,         fn (y, [_, Ty.DIM d1, Ty.SHAPE dd, Ty.DIM d2], xs) =>
                                          [assignEin(y, Mk.dotimes(d1, dd@[d2]), xs)]),
                (BV.op_Ddot,            fn (y, [_, Ty.DIM d1,  Ty.SHAPE dd, Ty.DIM d2], xs) =>
                                          [assignEin(y, Mk.divergence(d1, dd), xs)] ),
                (BV.op_norm_t,          fn (y, [sv], xs) => let
                                          val DstTy.TensorTy dd1 = shapeVarToTensor sv
                                          in
                                            case (dd1,xs)
                                             of ([], [arg0]) => [IR.ASSGN(y, IR.VAR arg0)]
                                              | _ => [assignEin(y, Mk.normT dd1, xs)]
                                            (* end case *)
                                          end),
                (BV.op_norm_f,          fn (y, [ _,Ty.DIM d1, Ty.SHAPE dd1], xs) => (case (dd1, xs)
                                           of ([], [arg0]) => [IR.ASSGN(y, IR.VAR arg0)]
                                            | _ => [assignEin(y, Mk.normF(d1, dd1), xs)]
                                          (* end case *))),
                (BV.op_not,             simpleOp Op.Not),
                (BV.op_cross3_tt,       simpleEOp Mk.cross3TT),
                (BV.op_cross2_tt,       simpleEOp Mk.cross2TT),
                (BV.op_cross2_ff,       simpleEOp Mk.cross2FF),
                (BV.op_cross3_ff,       simpleEOp Mk.cross3FF),
                (BV.op_cross2_ft,       simpleEOp Mk.cross2FT),
                (BV.op_cross3_ft,       simpleEOp Mk.cross3FT),
                (BV.op_cross2_tf,       simpleEOp Mk.cross2TF),
                (BV.op_cross3_tf,       simpleEOp Mk.cross3TF),
                (BV.op_outer_tt,        fn (y, [sh1, sh2, _], xs) => let
                                          val ty1 as DstTy.TensorTy dd1 = shapeVarToTensor sh1
                                          val ty2 as DstTy.TensorTy dd2 = shapeVarToTensor sh2
                                          in
                                            [assignEin(y, (Mk.outerTT(dd1, dd2)), xs)]
                                          end),
                (BV.op_outer_tf,        fn (y, [_, Ty.DIM d, sh1, Ty.SHAPE dd2, _], xs) => let
                                          val ty1 as DstTy.TensorTy dd1 = shapeVarToTensor sh1
                                          in
                                            [assignEin(y, Mk.outerTF(d, dd1, dd2), xs)]
                                          end),
                (BV.op_outer_ft,        fn (y, [_, Ty.DIM d, Ty.SHAPE dd1, sh2, _], xs) => let
                                          val ty1 as DstTy.TensorTy dd2 = shapeVarToTensor sh2
                                          in
                                            [assignEin(y, Mk.outerFT(d, dd1, dd2), xs)]
                                          end),
                (BV.op_outer_ff,        fn (y, [_, _, Ty.DIM d, Ty.SHAPE dd1, Ty.SHAPE dd2, _], xs) =>
                                          [assignEin(y, Mk.outerFF(d, dd1, dd2), xs)]),
                (BV.op_inner_tt,        fn (y, [sh1, sh2, _], xs) => let
                                          val ty1 as DstTy.TensorTy dd1 = shapeVarToTensor sh1
                                          val ty2 as DstTy.TensorTy dd2 = shapeVarToTensor sh2
                                          in
                                            [assignEin(y, (Mk.innerTT(dd1, dd2)), xs)]
                                          end),
                (BV.op_inner_tf,        fn (y, [_, Ty.DIM d, sh1, Ty.SHAPE dd2, _], xs) =>let
                                          val ty1 as DstTy.TensorTy dd1 = shapeVarToTensor sh1
                                          in
                                            [assignEin(y, Mk.innerTF(dd1, d, dd2), xs)]
                                          end),
                (BV.op_inner_ft,        fn (y, [_, Ty.DIM d, Ty.SHAPE dd1, sh2, _], xs) =>let
                                          val ty1 as DstTy.TensorTy dd2 = shapeVarToTensor sh2
                                          in
                                            [assignEin(y, Mk.innerFT(dd1, d, dd2), xs)]
                                          end),
                (BV.op_inner_ff,        fn (y,  [_, _, Ty.DIM d, Ty.SHAPE dd1, Ty.SHAPE dd2, _], xs) =>
                                          [assignEin(y, Mk.innerFF(dd1, d, dd2), xs)]),
                (BV.op_colon_tt,        fn (y, [sh1, sh2, _], xs) => let
                                          val ty1 as DstTy.TensorTy dd1 = shapeVarToTensor sh1
                                          val ty2 as DstTy.TensorTy dd2 = shapeVarToTensor sh2
                                          in
                                            [assignEin(y, Mk.colonTT(dd1, dd2), xs)]
                                          end),
                (BV.op_colon_ft,        fn (y, [_, Ty.SHAPE dd1, Ty.DIM d, Ty.SHAPE dd2, _], xs) =>
                                          [assignEin(y, Mk.colonFT(d, dd1, dd2), xs)]),
                (BV.op_colon_tf,        fn (y, [_, Ty.SHAPE dd1, Ty.DIM d, Ty.SHAPE dd2, _], xs) =>
                                          [assignEin(y, Mk.colonTF(d, dd1, dd2), xs)]),
                (BV.op_colon_ff,        fn (y, [_, Ty.SHAPE dd1, Ty.DIM d, Ty.SHAPE dd2, _], xs) =>
                                          [assignEin(y, Mk.colonFF(d, dd1, dd2), xs)]),
                (*  modulate is vector * vector pointwise multiplication *)
                (BV.fn_modulate,        fn (y, [Ty.DIM dd1], xs) =>
                                          [assignEin(y, (Mk.modulate dd1), xs)]),
                (BV.fn_normalize_t,     fn (y, [shp], xs) => let
                                          val DstTy.TensorTy dd1 = shapeVarToTensor shp
                                          in
                                            case (dd1, xs)
(* FIXME: this assignment is incorrect (there should be an absolute-value), but I don't
 * think that this case should ever arise.  Same for fn_normalize_f.
 *)
                                             of ([], [x]) => [IR.ASSGN(y, IR.VAR x)]
                                              | (_, [_]) => [assignEin(y, Mk.normalizeTT dd1, xs@xs)]
                                            (* end case *)
                                          end),
                (BV.fn_normalize_f,     fn (y, [ _,Ty.DIM d1, Ty.SHAPE dd1], xs) => (case (dd1, xs)
                                           of ([], [arg0]) => [IR.ASSGN(y, IR.VAR arg0)]
                                            | (_, [arg0]) => [assignEin(y, Mk.normalizeFF(d1, dd1), xs@xs)]
                                          (* end case *))),
                (BV.fn_trace_t,         fn (y, [Ty.DIM d], xs) =>
                                          [assignEin(y, (Mk.traceT d), xs)]),
                (BV.fn_trace_f,         fn (y, [_, Ty.DIM d, Ty.SHAPE dd], xs) =>
                                          [assignEin(y, Mk.traceF(d, dd), xs)]),
                (BV.fn_transpose_t,     fn (y, [Ty.DIM d1, Ty.DIM d2], xs) =>
                                          [assignEin(y, (Mk.transposeT [d1, d2]), xs)]),
                (BV.fn_transpose_f,     fn (y, [_, Ty.DIM d1, Ty.DIM d2, Ty.DIM d3], xs) =>
                                          [assignEin(y, (Mk.transposeF (d1, d2, d3)), xs)]),
                (BV.fn_det2_t,          simpleEOp (Mk.det2T)),
                (BV.fn_det3_t,          simpleEOp (Mk.det3T)),
                (BV.fn_det2_f,          simpleEOp (Mk.det2F)),
                (BV.fn_det3_f,          simpleEOp (Mk.det3F)),
                (BV.fn_sqrt_r,          fn (y, _, xs) =>
                                          [assignEin(y, Mk.sqrtR, xs)]),
                (BV.fn_sqrt_s,          fn (y, [_, Ty.DIM d1], xs) =>
                                          [assignEin(y, Mk.sqrtF d1, xs)]),
                (BV.fn_cos_r,           fn (y, _, xs) =>
                                          [assignEin(y, Mk.cosR, xs)]),
                (BV.fn_cos_s,           fn (y, [_, Ty.DIM d1], xs) =>
                                          [assignEin(y, Mk.cosF d1, xs)]),
                (BV.fn_acos_r,           fn (y, _, xs) =>
                                          [assignEin(y, Mk.acosR, xs)]),
                (BV.fn_acos_s,          fn (y, [_, Ty.DIM d1], xs) =>
                                          [assignEin(y, Mk.acosF d1, xs)]),
                (BV.fn_sin_r,           fn (y, _, xs) =>
                                          [assignEin(y, Mk.sinR, xs)]),
                (BV.fn_sin_s,           fn (y, [_, Ty.DIM d1], xs) =>
                                          [assignEin(y, Mk.sinF d1, xs)]),
                (BV.fn_asin_r,          fn (y, _, xs) =>
                                          [assignEin(y, Mk.asinR, xs)]),
                (BV.fn_asin_s,          fn (y, [_, Ty.DIM d1], xs) =>
                                          [assignEin(y, Mk.asinF d1, xs)]),
                (BV.fn_tan_r,           fn (y, _, xs) =>
                                          [assignEin(y, Mk.tanR, xs)]),
                (BV.fn_tan_s,           fn (y, [_, Ty.DIM d1], xs) =>
                                          [assignEin(y, Mk.tanF d1, xs)]),
                (BV.fn_atan_r,          fn (y, _, xs) =>
                                          [assignEin(y, Mk.atanR, xs)]),
                (BV.fn_atan_s,          fn (y, [_, Ty.DIM d1], xs) =>
                                          [assignEin(y, Mk.atanF d1, xs)]),
                (BV.fn_exp_r,           fn (y, _, xs) =>
                                          [assignEin(y, Mk.expT, xs)]),
                (BV.fn_exp_s,           fn (y, [_, Ty.DIM d1], xs) =>
                                          [assignEin(y, Mk.expF d1, xs)]),
(* FIXME:
                (BV.clamp_trr,          fn (y, [sv, dv], [x, lo, hi]) => let
					  in [
					  ] end),
*)
                (BV.clamp_ttt,          tensorOp Op.Clamp),
                (BV.lerp3,              tensorOp Op.Lerp),
                (BV.lerp5,              fn (y, [sv], [a, b, x0, x, x1]) => let
                                          val t1 = IR.Var.new("t1", DstTy.realTy)
                                          val t2 = IR.Var.new("t2", DstTy.realTy)
                                          val t3 = IR.Var.new("t3", DstTy.realTy)
                                          in [
                                            assignEin(t1, Mk.subRR, [x, x0]),
                                            assignEin(t2, Mk.subRR, [x1, x0]),
                                            assignEin(t3, Mk.divRR, [t1, t2]),
                                            IR.ASSGN(y, IR.OP(Op.Lerp(shapeVarToTensor sv), [a, b, t3]))
                                          ] end),
                (BV.evals2x2,           eigenVal (Op.Eigen2x2, 2)),
                (BV.evals3x3,           eigenVal (Op.Eigen3x3, 3)),
                (BV.evecs2x2,           eigenVec (Op.Eigen2x2, 2)),
                (BV.evecs3x3,           eigenVec (Op.Eigen3x3, 3)),
                (BV.fn_abs_i,           simpleOp (Op.Abs DstTy.IntTy)),
                (BV.fn_abs_r,           simpleOp (Op.Abs DstTy.realTy)),
                (BV.fn_max_i,           simpleOp (Op.Max DstTy.IntTy)),
                (BV.fn_max_r,           simpleOp (Op.Max DstTy.realTy)),
                (BV.fn_min_i,           simpleOp (Op.Min DstTy.IntTy)),
                (BV.fn_min_r,           simpleOp (Op.Min DstTy.realTy)),
                (BV.i2r,                simpleOp Op.IntToReal),
                (BV.identity,           fn (y, [Ty.DIM d], xs) =>
                                          [assignEin(y, Mk.identity d, xs)]),
(* FIXME: eventually zero should be implemented by Ein
                (BV.zero,               fn (y, [Ty.SHAPE dd], []) =>
                                          [assignEin(y, Mk.zeros dd, [])]),
*)
                (BV.zero,               fn (y, [sv], []) =>
                                          assign(y, Op.Zero(shapeVarToTensor sv), [])),
                (BV.nan,                fn (y, [Ty.SHAPE dd], []) => let
                                            val nan = IR.LIT(Literal.Real(RealLit.nan))
                                            fun mk (y, [], stms) = IR.ASSGN(y, nan) :: stms
                                              | mk (y, d::dd, stms) = let
                                                  val ty = shapeVarToTensor(Ty.SHAPE dd)
                                                  val zs = List.tabulate(d, fn _ => IR.Var.new("_nan", ty))
                                                  in
                                                    IR.ASSGN(y, IR.CONS(zs, IR.Var.ty y)) ::
                                                      List.foldl (fn (z, stms) => mk(z, dd, stms)) stms zs
                                                  end
                                            in
                                              List.rev (mk (y, dd, []))
                                            end),
              (* sequence operations *)
                (BV.subscript,          fn (y, [tv, Ty.DIM d], args) =>
                                          assign(y,
                                            Op.Subscript(DstTy.SeqTy(trType tv, SOME d)),
                                            args)),
                (BV.dynSubscript,       fn (y, [tv], args) =>
                                          assign(y, Op.Subscript(DstTy.SeqTy(trType tv, NONE)), args)),
                (BV.at_Td,              fn (y, [tv], args) => assign(y, Op.Prepend(trType tv), args)),
                (BV.at_dT,              fn (y, [tv], args) => assign(y, Op.Append(trType tv), args)),
                (BV.at_dd,              fn (y, [tv], args) => assign(y, Op.Concat(trType tv), args)),
                (BV.range,              fn (y, _, args) => assign(y, Op.Range, args)),
                (BV.fn_length,          fn (y, [tv], [s]) => assign(y, Op.Length(trType tv), [s])),
              (* image operations *)
                (BV.fn_size,            fn (y, [Ty.DIM d, _], [img]) => let
                                          val DstTy.ImageTy info = IR.Var.ty img
                                        (* we extract each dimension separately and then build the sequence value *)
                                          val dims = List.tabulate(d, fn i => IR.Var.new("i"^Int.toString i, DstTy.IntTy))
                                          fun mkStms ([], _, stms) = stms (* in reverse order! *)
                                            | mkStms (d::dr, i, stms) = mkStms (dr, i+1,
                                                IR.ASSGN(d, IR.OP(Op.ImageDim(info, i), [img])) :: stms)
                                          in
                                            List.revAppend (mkStms (dims, 0, []), [
                                                IR.ASSGN(y, IR.SEQ(dims, DstTy.SeqTy(DstTy.intTy, SOME d)))
                                              ])
                                          end),
                (BV.image_border,       fn (y, _, args as [img, _]) => let
                                          val DstTy.ImageTy info = IR.Var.ty img
                                          in
                                            assign(y, Op.BorderCtlDefault info, args)
                                          end),
                (BV.image_clamp,        fn (y, _, args as [img]) => let
                                          val DstTy.ImageTy info = IR.Var.ty img
                                          in
                                            assign(y, Op.BorderCtlClamp info, args)
                                          end),
                (BV.image_mirror,       fn (y, _, args as [img]) => let
                                          val DstTy.ImageTy info = IR.Var.ty img
                                          in
                                            assign(y, Op.BorderCtlMirror info, args)
                                          end),
                (BV.image_wrap,         fn (y, _, args as [img]) => let
                                          val DstTy.ImageTy info = IR.Var.ty img
                                          in
                                            assign(y, Op.BorderCtlWrap info, args)
                                          end),
                (BV.dist2_t,           fn (y, _, xs) => dist(y, 2, xs)),
                (BV.dist3_t,           fn (y, _, xs) => dist(y, 3, xs)),
              (* reduction operators *)
                (BV.red_all,            fn (y, _, args as [e, v, k]) =>
                                          assign(y, Op.R_All(IR.Var.ty v), args)),
                (BV.red_exists,         fn (y, _, args as [e, v, k]) =>
                                          assign(y, Op.R_Exists(IR.Var.ty v), args)),
                (BV.red_max,            fn (y, _, args as [e, v, k]) =>
                                          assign(y, Op.R_Max(IR.Var.ty v), args)),
                (BV.red_mean,           fn (y, _, args as [e, v, k]) =>
                                          assign(y, Op.R_Mean(IR.Var.ty v), args)),
                (BV.red_min,            fn (y, _, args as [e, v, k]) =>
                                          assign(y, Op.R_Min(IR.Var.ty v), args)),
                (BV.red_product,        fn (y, _, args as [e, v, k]) =>
                                          assign(y, Op.R_Product(IR.Var.ty v),args)),
                (BV.red_sum,            fn (y, _, args as [e, v, k]) =>
                                          assign(y, Op.R_Sum(IR.Var.ty v), args)),
                (BV.red_variance,       fn (y, _, args as [e, v, k]) =>
                                          assign(y, Op.R_Variance(IR.Var.ty v), args)),
              (* spatial queries *)
                (BV.fn_sphere_im,       fn (y, [tv], args as [p, s]) =>
                                          assign(y, Op.SphereQuery(IR.Var.ty p, trType tv), args)),
                (BV.fn_sphere1_r,       fn (y, [tv], args as [p, s]) =>
                                          assign(y, Op.SphereQuery(IR.Var.ty p, trType tv), args)),
                (BV.fn_sphere2_t,       fn (y, [tv], args as [p, s]) =>
                                          assign(y, Op.SphereQuery(IR.Var.ty p, trType tv), args)),
                (BV.fn_sphere3_t,       fn (y, [tv], args as [p, s]) =>
                                          assign(y, Op.SphereQuery(IR.Var.ty p, trType tv), args)),
              (* math functions that have not been lifted *)
                (BV.fn_atan2_rr,        fn (y, _, args) =>
                                          assign(y, Op.MathFn MathFns.ATAN2, args)),
                (BV.fn_ceil_r,          fn (y, _, args) =>
                                          assign(y, Op.MathFn MathFns.CEIL, args)),
                (BV.fn_floor_r,         fn (y, _, args) =>
                                          assign(y, Op.MathFn MathFns.FLOOR, args)),
                (BV.fn_fmod_rr,         fn (y, _, args) =>
                                          assign(y, Op.MathFn MathFns.FMOD, args)),
                (BV.fn_erf_r,           fn (y, _, args) =>
                                          assign(y, Op.MathFn MathFns.ERF, args)),
                (BV.fn_erfc_r,          fn (y, _, args) =>
                                          assign(y, Op.MathFn MathFns.ERFC, args)),
                (BV.fn_log_r,           fn (y, _, args) =>
                                          assign(y, Op.MathFn MathFns.LOG, args)),
                (BV.fn_log10_r,         fn (y, _, args) =>
                                          assign(y, Op.MathFn MathFns.LOG10, args)),
                (BV.fn_log2_r,          fn (y, _, args) =>
                                          assign(y, Op.MathFn MathFns.LOG2, args)),
                (BV.fn_pow_rr,          fn (y, _, args) =>
                                          assign(y, Op.MathFn MathFns.POW, args))
              ];
            tbl
          end

    fun translate (y, f, mvs, xs) = (case VTbl.find tbl f
           of SOME transFn => transFn(y, mvs, xs)
            | NONE => raise Fail("TranslateBasis.translate: unknown basis function " ^ Var.uniqueNameOf f)
          (* end case *))
handle ex => (print(concat["translate (", IR.Var.toString y, ", ",
Var.uniqueNameOf f, ", ...)\n"]); raise ex)

  end

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