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

SCM Repository

[diderot] View of /branches/vis12/src/compiler/c-target/gen-output.sml
ViewVC logotype

View of /branches/vis12/src/compiler/c-target/gen-output.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1707 - (download) (annotate)
Thu Mar 8 12:13:35 2012 UTC (7 years, 5 months ago) by jhr
File size: 6761 byte(s)
  Working on code to generate get output library functions
(* gen-output.sml
 *
 * COPYRIGHT (c) 2012 The Diderot Project (http://diderot-language.cs.uchicago.edu)
 * All rights reserved.
 *
 * Generate strand output functions
 *)

structure GenOutput : sig

    val gen : TargetUtil.target_desc * int option -> (TreeIL.Ty.ty * string) -> CLang.decl

  end = struct

    structure IL = TreeIL
    structure V = IL.Var
    structure Ty = IL.Ty
    structure CL = CLang
    structure N = CNames

    fun mapi f l = let
	  fun mapf (i, [], l) = List.rev l
	    | mapf (i, x::xs, l) = mapf (i+1, xs, f(i, x)::l)
	  in
	    mapf (0, l, [])
	  end

(* cases:
 *	grid, fixed-size elements
 *	collection, fixed-size elements
 *	grid, dynamic-size elements
 *	collection, dynamic-size elements
 *)

    val nrrdPtrTy = CL.T_Ptr(CL.T_Named "Nrrd")
    val sizeTy = CL.T_Named "size_t"

    fun mkInt i = CL.mkInt(IntInf.fromInt i)

(* FIXME: this is a copy of the function in gen-library-interface.sml *)
  (* translate TreeIL types to CLang types *)
    fun trType ty = (case ty
           of Ty.BoolTy => CL.T_Named "bool"
            | Ty.StringTy => CL.charPtr
            | Ty.IntTy => !N.gIntTy
            | Ty.TensorTy[] => !N.gRealTy
            | Ty.TensorTy[n] => CL.T_Array(!N.gRealTy, SOME n)
            | Ty.TensorTy[n, m] => CL.T_Array(CL.T_Array(!N.gRealTy, SOME n), SOME m)
            | Ty.TensorTy[n, m, l] => CL.T_Array(CL.T_Array(CL.T_Array(!N.gRealTy, SOME n), SOME m), SOME l)
            | Ty.SeqTy(Ty.IntTy, n) => CL.T_Array(!N.gIntTy, SOME n)
            | Ty.SeqTy(ty, n) => CL.T_Array(trType ty, SOME n)
            | Ty.DynSeqTy _ => CL.T_Ptr(CL.T_Named N.dynSeqTy)
            | Ty.AddrTy(ImageInfo.ImgInfo{ty=(_, rTy), ...}) => CL.T_Ptr(CL.T_Num rTy)
            | Ty.ImageTy(ImageInfo.ImgInfo{dim, ...}) => CL.T_Ptr(CL.T_Named(N.imageTy dim))
            | _ => raise Fail(concat["GetOutput.trType(", Ty.toString ty, ")"])
          (* end case *))

    fun infoOf (tgt : TargetUtil.target_desc, ty) = (case ty
           of Ty.IntTy => if #longint tgt
		then (CL.int64, "nrrdTypeLLong", [1])
		else (CL.int32, "nrrdTypeInt", [1])
            | Ty.TensorTy [] => if #double tgt
		then (CL.double, "nrrdTypeDouble", [1])
		else (CL.float, "nrrdTypeFloat", [1])
            | Ty.TensorTy dims => if #double tgt
		then (CL.double, "nrrdTypeDouble", dims)
		else (CL.float, "nrrdTypeFloat", dims)
            | Ty.SeqTy(ty, n) => let
		val (elemTy, nrrdTy, dims) = infoOf (tgt, ty)
		in
		  (elemTy, nrrdTy, n::dims)
		end
            | _ => raise Fail(concat["GetOutput.infoOf(", Ty.toString ty, ")"])
	  (* end case *))

  (* variables in the generated code *)
    val wrldV = CL.mkVar "wrld"
    val sizesV = CL.mkVar "sizes"
    val iV = CL.mkVar "i"
    val pV = CL.mkVar "p"
    val nrrdV = CL.mkVar "nrrd"
    val numStableV = CL.mkVar "numStableV"
    val DIDEROT_STABLE = CL.mkVar "DIDEROT_STABLE"

  (* code fragment for counting the number of stable strands
	size_t numStabilized = 0;
	for (unsigned int i = 0;  i < wrld->numStrands;  i++) {
	    if (wrld->status[i] == DIDEROT_STABLE)
		numStabilized++;
	}
  *)
    val countStable = [
	    CL.mkDecl(sizeTy, "numStable", SOME(CL.I_Exp(mkInt 0))),
	    CL.mkFor(
	      [(CL.uint32, "i", mkInt 0)],
	      CL.mkBinOp(iV, CL.#<, CL.mkIndirect(wrldV, "numStrands")),
	      [CL.mkPostOp(numStableV, CL.^++)],
	      CL.mkIfThen(
		CL.mkBinOp(CL.mkSubscript(CL.mkIndirect(wrldV, "status"), iV), CL.#==, DIDEROT_STABLE),
		CL.S_Exp(CL.mkPostOp(numStableV, CL.^++))))
	  ]

    fun genDynOutput (tgt, isArray, ty, name) = raise Fail "genDynOutput"

  (* create the body of an output function for fixed-size outputs.  The structure of the
   * function body is:
   *
   *	declare and compute sizes array
   *	allocate nrrd data
   *	copy data from strands to nrrd
   *)
    fun genFixedOutput (tgt, nAxes, ty, name) = let
	  val (elemCTy, nrrdType, dims) = infoOf (tgt, ty)
	  val nDims = List.length dims
	  val nElems = List.foldl Int.* 1 dims
	  val (isArray, nAxes) = (case nAxes of NONE => (false, 1) | SOME n => (true, n))
	(* generate the sizes initialization code *)
	  val initSizes = let
		fun sizes i = CL.mkSubscript(sizesV, mkInt i)
		val sizesDcl = CL.mkDecl(CL.T_Array(sizeTy, SOME(nDims+nAxes)), "sizes", NONE)
		fun setSizes (i, v) = CL.mkAssign(sizes i, v)
		val dimSizes = sizesDcl :: mapi (fn (i, d) => setSizes(i, mkInt d)) dims
		in
		  if isArray
		    then dimSizes @
		      List.tabulate (nAxes, fn i =>
			setSizes(nDims+i, CL.mkSubscript(CL.mkIndirect(wrldV, "sizes"), mkInt(nAxes-i-1))))
		    else countStable @ dimSizes @ [setSizes(nDims, numStableV)]
		end
	(* generate the copy code *)
	  val copyCode = let
		val pDecl = CL.mkDecl(CL.charPtr, "p", SOME(CL.I_Exp(
			CL.mkCast(CL.charPtr, CL.mkIndirect(nrrdV, "data")))))
		val copyCore = CL.mkBlock[
			CL.mkCall("memcpy", [
			    pV,
			    CL.mkUnOp(CL.%&,
			      CL.mkIndirect(
				CL.mkSubscript(CL.mkIndirect(wrldV, "outState"), iV), name)),
			    CL.mkBinOp(mkInt nDims, CL.#*, CL.mkSizeof elemCTy)
			  ]),
			CL.mkExpStm(CL.mkAssignOp(pV, CL.+=, CL.mkSizeof elemCTy))
		      ]
		fun mkLoop stm = CL.mkFor(
		      [(CL.uint32, "i", CL.mkInt 0)],
		      CL.mkBinOp(iV, CL.#<, CL.mkIndirect(wrldV, "numStrands")),
		      [CL.mkPostOp(iV, CL.^++)],
		      stm)
		in
		  if isArray
		    then [pDecl, mkLoop copyCore]
		    else raise Fail "FIXME"
		end
	(* the function body *)
	  val stms =
		CL.mkComment["Compute sizes of nrrd file"] ::
		CL.mkDecl(sizeTy, "sizes", NONE) ::
		initSizes @
		CL.mkComment["Allocate nrrd data"] ::
	      (*
		  if (nrrdMaybeAlloc_nva(nrrd, nrrdFloatType, 3, sizes) != 0) {
		      wrld->err = biffGetDone(NRRD);
		      return true;
		  }
	      *)
		CL.mkIfThen(
		  CL.mkBinOp(
		    CL.mkApply("nrrdMaybeAlloc_nva", [
			CL.mkVar "nrrd", CL.mkVar nrrdType, mkInt(nDims+nAxes), CL.mkVar "sizes"
		      ]),
		    CL.#!=,
		    CL.mkInt 0),
		(* then *)
		  CL.mkBlock[
		      CL.mkAssign(CL.mkIndirect(CL.mkVar "wrld", "err"),
			CL.mkApply("biffGetDone", [CL.mkVar "NRRD"])),
		      CL.mkReturn(SOME(CL.E_Var "true"))
		    ]
		(* endif*)) ::
		CL.mkComment["copy data to output nrrd"] ::
		copyCode @
		[CL.mkReturn(SOME(CL.E_Var "false"))]
	  in
	    ([CL.PARAM([], nrrdPtrTy, "nrrd")], CL.mkBlock stms)
	  end

    fun gen (tgt : TargetUtil.target_desc, nAxes) (ty, name) = let
	  val funcName = String.concat[#namespace tgt, "Get_", name]
	  val wrldPtr = CL.T_Ptr(CL.T_Named(#namespace tgt ^ "World_t"))
	  fun mkFunc (params, body) =
		CL.D_Func([], CL.boolTy, funcName, CL.PARAM([], wrldPtr, "wrld")::params, body)
	  in
	    case ty
	     of Ty.DynSeqTy ty' => mkFunc (genDynOutput(tgt, nAxes, ty', name))
	      | _ => mkFunc (genFixedOutput(tgt, nAxes, ty, name))
	    (* end case *)
	  end

  end

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