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

SCM Repository

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

View of /branches/vis12-cl/src/compiler/cl-target/gen-inputs.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2726 - (download) (annotate)
Wed Sep 24 19:12:59 2014 UTC (5 years ago) by jhr
File size: 5282 byte(s)
  Working on OpenCL support
(* gen-inputs.sml
 *
 * COPYRIGHT (c) 2014 The Diderot Project (http://diderot-language.cs.uchicago.edu)
 * All rights reserved.
 *
 * Generate code to handle input variables for the OpenCL target.
 *)

structure GenInputs : sig

  (* input variable descriptor: type, name, description, and default *)
    type input_desc = (TreeIL.Ty.ty * string * string option * TreeIL.exp option)

    val gatherInputs : TreeIL.block -> input_desc list

  (*** Support for standalone executables ***)

  (* generate the input initialization structure that we use to initialize input
   * globals from command-line arguments in stand-alone executables.
   *)
    val genInputsStruct : Properties.props * input_desc list -> CLang.decl

  (* generate the functions that handle inputs for standalone executables.  These are:
   *	InitDefaults	-- called to initialize the default input values
   *	RegisterInputs	-- called to register the command-line options for the input globals
   *	InitInputs	-- called to initialize the input globals from the values specified
   *			   on the command line.
   *)
    val genExecInputFuns : Properties.props * input_desc list -> CLang.decl list

  (*** Support for libraries ***)

  (* generate the typedef for the defined-input flag struct. *)
    val genDefinedInpStruct : Properties.props * input_desc list -> CLang.decl

  (* generated the functions to initialize inputs for the library API.  This function also
   * generates the function to initialize the defined input flags struct.
   *)
    val genInputFuns : Properties.props * input_desc list -> CLang.decl list

  end = struct

    structure Ty = TreeIL.Ty
    structure CL = CLang
    structure N = CNames
    structure TrTy = CTyTranslate
    structure U = GenInputsUtil

    type input_desc = U.input_desc

    val gatherInputs = U.gatherInputs
    val genInputsStruct = U.genInputsStruct
    val genDefinedInpStruct = U.genDefinedInpStruct

    val nrrdPtrTy = CL.T_Ptr(CL.T_Named "Nrrd")
    val wrldPrefixTy = CL.T_Ptr(CL.T_Named "WorldPrefix_t")

  (* world pointer cast to the world prefix type *)
    val wrldPrefix = CL.mkCast(wrldPrefixTy, CL.mkVar "wrld")

  (* an l-value expression for accessing a global variable *)
    fun global name = CL.mkIndirect(CL.mkIndirect(CL.mkVar "wrld", "globals"), name)

  (* generate code to initialize the global input variables from the command-line inputs *)
    fun genInitInputs (tgt, inputs) = let
	(* the world pointer type *)
	  val worldPtrTy = CL.T_Ptr(CL.T_Named(N.worldTy tgt))
	(* the global state pointer type *)
	  val globPtrTy = CL.T_Ptr(CL.T_Named(N.globalTy tgt))
	(* the inputs pointer type *)
	  val inputPtrTy = CL.T_Ptr(CL.T_Named(N.inputsTy tgt))
	(* some common variables *)
	  val inpV = CL.mkVar "inp"
	  val optsV = CL.mkVar "opts"
	(* initialize a given input global; for sequences and images, this requires
	 * loading the value from the specified nrrd file, while for other types
	 * we just copy the values.
	 *)
	  fun initInput ((Ty.DynSeqTy elemTy, name, desc, optDflt), stms) = let
		val (loadFn, nDims, dims) = (case elemTy
		       of Ty.BoolTy => ("Diderot_DynSeqLoadBoolFromFile", CL.mkInt 0, CL.mkInt 0)
			| Ty.IntTy => ("Diderot_DynSeqLoadIntFromFile", CL.mkInt 0, CL.mkInt 0)
			| Ty.TensorTy[] => ("Diderot_DynSeqLoadRealFromFile", CL.mkInt 0, CL.mkInt 0)
			| Ty.TensorTy _ => raise Fail "TODO: sequences of tensors"
			| Ty.SeqTy elemTy => raise Fail "TODO: sequences of sequences"
			| _ => raise Fail "unsupported dynamic sequence type"
		      (* end case *))
		in
		  CL.mkAssign(global name,
		    CL.mkApply(loadFn, [wrldPrefix, CL.mkIndirect(inpV, name), nDims, dims])) ::
		  CL.mkIfThen(CL.mkBinOp(global name, CL.#==, CL.mkInt 0),
		    CL.mkReturn(SOME(CL.mkVar "true"))) :: stms
		end
	    | initInput ((Ty.ImageTy info, name, desc, optDflt), stms) = let
		val loadFn = (case ImageInfo.dim info
		       of 1 => "Diderot_LoadImage1D"
			| 2 => "Diderot_LoadImage2D"
			| 3 => "Diderot_LoadImage3D"
			| _ => raise Fail "image with dimension > 3"
		      (* end case *))
		in
		  CL.mkIfThen(
		    CL.mkApply(loadFn, [wrldPrefix, CL.mkIndirect(inpV, name), CL.mkAddrOf(global name)]),
		    CL.mkReturn(SOME(CL.mkVar "true"))) :: stms
		end
	    | initInput ((ty, name, _, _), stms) =
		TrTy.copyFromC{ty=ty, dst=global name, src=CL.mkIndirect(inpV, name)} @ stms
	  in
	    CL.D_Func(
	      ["static"], CL.boolTy, N.initInputs,
	      [CL.PARAM([], worldPtrTy, "wrld"), CL.PARAM([], inputPtrTy, "inp")],
	      CL.mkBlock(
		CL.mkDeclInit(globPtrTy, "glob", CL.mkIndirect(CL.mkVar "wrld", "globals")) ::
		List.foldr initInput [CL.mkReturn(SOME(CL.mkVar "false"))] inputs))
	  end

  (* generate the functions that handle inputs for standalone executables.  These are:
   *	InitDefaults	-- called to initialize the default input values
   *	RegisterInputs	-- called to register the command-line options for the input globals
   *	InitInputs	-- called to initialize the input globals from the values specified
   *			   on the command line.
   *)
    fun genExecInputFuns arg = U.genExecInputFuns arg @ [genInitInputs arg]

  (* for each input variable we generate two or three top-level declarations in the
   * exported API.
   *)
    fun genInputFuns (tgt, inputs) = [] (* FIXME *)

  end

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