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 3118 - (download) (annotate)
Mon Mar 23 18:05:45 2015 UTC (4 years, 1 month ago) by jhr
File size: 6988 byte(s)
  working on OpenCL issues
(* 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 = GenInputsUtil.input_desc

    val gatherInputs : TreeIL.block -> input_desc list

  (* extract the world struct fields for the image data buffers and initialization kernels *)
    val getBuffersAndKernels : input_desc list -> (string list * string 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 list

  (* 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 list

  (* 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 GVar = TreeIL.GlobalVar
    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")

  (* extract the world struct fields for the image data buffers and initialization kernels *)
    fun getBuffersAndKernels inputs = let
	  fun get ([], bufs, kerns) = (List.rev bufs, List.rev kerns)
	    | get ((gv, name, _, _)::inps, bufs, kerns) = (case GVar.ty gv
		 of Ty.ImageTy _ => get (inps, (name ^ "Buf") :: bufs, (name ^ "Kern") :: kerns)
		  | _ => get (inps, bufs, kerns)
		(* end case *))
	  in
	    get (inputs, [], [])
	  end

  (* generate code to initialize the global input variables from the command-line inputs *)
    fun genInitInputs (tgt, inputs) = let
	(* the world pointer type *)
	  val worldPtrTy = N.worldPtrTy tgt
	(* the inputs pointer type *)
	  val inputPtrTy = N.inputsPtrTy tgt
	(* some common variables *)
	  val wrldV = CL.mkVar "wrld"
	  val inpV = CL.mkVar "inp"
	(* 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 initInputs ((gv, name, _, optDflt)::inps, flds, stms, kerns) = (case GVar.ty gv
		 of Ty.DynSeqTy elemTy =>
		      raise Fail "dynamic sequences not supported for OpenCL"
		  | Ty.ImageTy info => let
		      val loadFn = (case ImageInfo.dim info
			     of 1 => "Diderot_LoadGPUImage1D"
			      | 2 => "Diderot_LoadGPUImage2D"
			      | 3 => "Diderot_LoadGPUImage3D"
			      | _ => raise Fail "image with dimension > 3"
			    (* end case *))
		      val stm = CL.mkIfThen(
			    CL.mkApply(loadFn, [
				CL.mkCast(CL.T_Ptr(CL.T_Named "OCLWorldPrefix_t"), CL.mkVar "wrld"),
				CL.mkIndirect(wrldV, "globalsBuf"),
				CL.mkIndirect(inpV, "gv_" ^ name),
				CL.mkIndirect(wrldV, name ^ "Kern"),
				CL.mkAddrOf(CL.mkIndirect(wrldV, name ^ "Buf"))
			      ]),
			    CL.mkReturn(SOME(CL.mkVar "true")))
		      in
			initInputs (inps, name::flds, stm::stms, kerns)
		      end
		  | ty => let
		      val stm = TrTy.copyFromC{
			      ty=ty,
			      dst=CL.mkSelect(CL.mkVar "inputs", name),
			      src=CL.mkIndirect(inpV, name)
			    }
		      in
			initInputs (inps, name::flds, List.revAppend(stm, stms), kerns)
		      end
		(* end case *))
	    | initInputs ([], flds, stms, kerns) = (List.rev flds, List.rev stms, List.rev kerns)
	  val (flds, stms, kerns) = initInputs (inputs, [], [], [])
(* TODO: create struct type from fields and copy to GPU; also generate kernels for images *)
	  val initFn = CL.D_Func(
		["static"], CL.boolTy, N.initInputs,
		[CL.PARAM([], worldPtrTy, "wrld"), CL.PARAM([], inputPtrTy, "inp")],
		CL.mkBlock(stms @ [CL.mkReturn(SOME(CL.mkVar "false"))]))
	  in
	    initFn
	  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]

    fun genCheckInputs (tgt, inputs) = let
	(* the world pointer type *)
	  val worldPtrTy = N.worldPtrTy tgt
          val wrldParam = CL.PARAM([], worldPtrTy, "wrld")
	(* check that the specified input has been defined and, if not, define it to its default *)
(* FIXME
	  fun check (ty, name, _, optDflt) = let
		val dfltStm = (case optDflt
		       of SOME v => let
			  (* get default file name for images and sequences *)
			    fun getName () = (case v
				   of IL.E_Lit(Literal.String s) => CL.mkStr s
				    | _ => raise Fail "expected string for default nrrd"
				  (* end case *))
			    in
			      case ty
			       of Ty.DynSeqTy elemTy =>
				    GenLoadNrrd.loadSeqFromFile (global gv, elemTy, getName())
				| Ty.ImageTy info =>
				    GenLoadNrrd.loadImage (global gv, info, getName())
				| _ => CL.mkBlock(ToC.trAssign(ToC.empty, global gv, v))
			      (* end case *)
			    end
			| NONE => CL.mkBlock[
			      World.errorMsgAdd(CL.mkStr(concat["undefined input \"", name, "\"\n"])),
			      CL.mkReturn(SOME(CL.mkBool true))
			    ]
		      (* end case *))
		in
		  CL.mkIfThen(CL.mkUnOp(CL.%!, U.defined name), dfltStm)
		end
*)
	  in
	    CL.D_Func(
	      ["static"], CL.boolTy, N.checkDefined tgt,
	      [wrldParam],
	      CL.mkReturn(SOME(CL.mkBool false)))
	  end

  (* for each input variable we generate two or three top-level declarations in the
   * exported API.
   *)
    fun genInputFuns (tgt, inputs) = let
	  val extras = [
		  genCheckInputs (tgt, inputs),
		  U.genDefineInp (tgt, inputs)
		]
          in
            extras
          end

  end

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