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

SCM Repository

[diderot] Annotation of /branches/vis15/src/compiler/target-cpu/gen-inputs.sml
ViewVC logotype

Annotation of /branches/vis15/src/compiler/target-cpu/gen-inputs.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3911 - (view) (download)

1 : jhr 3909 (* gen-inputs.sml
2 :     *
3 :     * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
4 :     *
5 :     * COPYRIGHT (c) 2016 The University of Chicago
6 :     * All rights reserved.
7 :     *
8 :     * Generate code to handle input variables for the C target.
9 :     *)
10 :    
11 :     structure GenInputs : sig
12 :    
13 :     (* input variable descriptor: type, name, description, and default *)
14 :     type input_desc = GenInputsUtil.input_desc
15 :    
16 :     (*** Support for standalone executables ***)
17 :    
18 :     (* generate the functions that handle inputs for standalone executables. These are:
19 :     * InitDefaults -- called to initialize the default input values
20 :     * RegisterInputs -- called to register the command-line options for the input globals
21 :     * InitInputs -- called to initialize the input globals from the values specified
22 :     * on the command line.
23 :     *)
24 :     val genExecInputFuns : CodeGenEnv.t * input_desc list -> CLang.decl list
25 :    
26 :     (*** Support for libraries ***)
27 :    
28 :     (* generate the typedef for the defined-input flag struct. *)
29 : jhr 3910 val genDefinedInpStruct : CodeGenEnv.t * input_desc list -> CLang.decl list
30 : jhr 3909
31 :     (* generated the functions to initialize inputs for the library API. This function also
32 :     * generates the function to initialize the defined input flags struct.
33 :     *)
34 : jhr 3910 val genInputFuns : CodeGenEnv.t * input_desc list -> CLang.decl list
35 : jhr 3909
36 :     end = struct
37 :    
38 :     structure IR = TreeIR
39 :     structure Ty = TreeIR.Ty
40 : jhr 3910 structure GVar = TreeGlobalVar
41 : jhr 3909 structure CL = CLang
42 : jhr 3910 structure RN = CxxNames
43 :     structure ToC = TreeToCxx
44 : jhr 3909 structure U = GenInputsUtil
45 : jhr 3910 structure Env = CodeGenEnv
46 : jhr 3911 structure GenAPI = GenLibraryInterface
47 : jhr 3909
48 :     type input_desc = U.input_desc
49 :    
50 :     val genDefinedInpStruct = U.genDefinedInpStruct
51 :    
52 : jhr 3910 (* translate an API type to the C types used to represent it in the external API *)
53 :     val trType = CodeGenUtil.trAPIType
54 : jhr 3909
55 :     val nrrdPtrTy = CL.T_Ptr(CL.T_Named "Nrrd")
56 :    
57 : jhr 3910 (* world pointer *)
58 :     val wrldV = CL.mkVar "wrld"
59 : jhr 3909
60 :     (* an l-value expression for accessing a global variable *)
61 :     fun global gv = CL.mkIndirect(CL.mkIndirect(CL.mkVar "wrld", "globals"), GVar.name gv)
62 :    
63 :     (* generate code to initialize the global input variables from the command-line inputs *)
64 : jhr 3910 fun genInitInputs (env, inputs) = let
65 : jhr 3909 (* the world pointer type *)
66 : jhr 3910 val worldPtrTy = RN.worldPtrTy
67 : jhr 3909 (* the global state pointer type *)
68 : jhr 3910 val globPtrTy = RN.globalPtrTy
69 : jhr 3909 (* the inputs pointer type *)
70 : jhr 3910 val optionsPtrTy = RN.optionsPtrTy env
71 : jhr 3909 (* some common variables *)
72 :     val inpV = CL.mkVar "inp"
73 :     val optsV = CL.mkVar "opts"
74 :     (* initialize a given input global; for sequences and images, this requires
75 :     * loading the value from the specified nrrd file, while for other types
76 :     * we just copy the values.
77 :     *)
78 : jhr 3911 fun initInput (Inputs.INP{var, name, ty, desc, init}, stms) = (case ty
79 : jhr 3910 of Ty.SeqTy(elemTy, NONE) => let
80 : jhr 3909 val (loadFn, nDims, dims) = (case elemTy
81 : jhr 3910 of Ty.BoolTy => ("diderot::load_dynseq<bool>", CL.mkInt 0, CL.mkInt 0)
82 : jhr 3909 | Ty.IntTy => ("Diderot_DynSeqLoadIntFromFile", CL.mkInt 0, CL.mkInt 0)
83 :     | Ty.TensorTy[] => ("Diderot_DynSeqLoadRealFromFile", CL.mkInt 0, CL.mkInt 0)
84 :     | Ty.TensorTy _ => raise Fail "TODO: sequences of tensors"
85 :     | Ty.SeqTy elemTy => raise Fail "TODO: sequences of sequences"
86 :     | _ => raise Fail "unsupported dynamic sequence type"
87 :     (* end case *))
88 :     in
89 : jhr 3911 CL.mkAssign(global var,
90 :     CL.mkApply(loadFn, [wrldV, CL.mkIndirect(inpV, GVar.name var), nDims, dims])) ::
91 :     CL.mkIfThen(CL.mkBinOp(global var, CL.#==, CL.mkInt 0),
92 : jhr 3909 CL.mkReturn(SOME(CL.mkVar "true"))) :: stms
93 :     end
94 : jhr 3910 | Ty.ImageTy(dim, _) => let
95 :     val loadFn = (case dim
96 : jhr 3909 of 1 => "Diderot_LoadImage1D"
97 :     | 2 => "Diderot_LoadImage2D"
98 :     | 3 => "Diderot_LoadImage3D"
99 :     | _ => raise Fail "image with dimension > 3"
100 :     (* end case *))
101 :     in
102 :     CL.mkIfThen(
103 : jhr 3911 CL.mkApply(loadFn, [
104 :     wrldV, CL.mkIndirect(inpV, GVar.name var), CL.mkAddrOf(global var)
105 :     ]),
106 : jhr 3909 CL.mkReturn(SOME(CL.mkVar "true"))) :: stms
107 :     end
108 : jhr 3911 | ty => TrTy.copyFromC{ty=ty, dst=global var, src=CL.mkIndirect(inpV, GVar.name var)} @ stms
109 : jhr 3909 (* end case *))
110 :     in
111 :     CL.D_Func(
112 :     ["static"], CL.boolTy, N.initInputs,
113 : jhr 3910 [CL.PARAM([], worldPtrTy, "wrld"), CL.PARAM([], optionsPtrTy, "inp")],
114 : jhr 3909 CL.mkBlock(
115 : jhr 3910 CL.mkDeclInit(globPtrTy, RN.globalsVar, CL.mkIndirect(CL.mkVar "wrld", "_globals")) ::
116 : jhr 3909 List.foldr initInput [CL.mkReturn(SOME(CL.mkVar "false"))] inputs))
117 :     end
118 :    
119 :     (* generate the functions that handle inputs for standalone executables. These are:
120 :     * InitDefaults -- called to initialize the default input values
121 :     * RegisterInputs -- called to register the command-line options for the input globals
122 :     * InitInputs -- called to initialize the input globals from the values specified
123 :     * on the command line.
124 :     *)
125 :     fun genExecInputFuns (_, []) = []
126 :     | genExecInputFuns arg = U.genExecInputFuns arg @ [genInitInputs arg]
127 :    
128 : jhr 3910 fun genCheckInputs (env, inputs) = let
129 : jhr 3909 (* the world pointer type *)
130 : jhr 3910 val worldPtrTy = N.worldPtrTy env
131 : jhr 3909 val wrldParam = CL.PARAM([], worldPtrTy, "wrld")
132 :     (* check that the specified input has been defined and, if not, define it to its default *)
133 : jhr 3911 fun check (Inputs.INP{var, name, init, ...}) = let
134 :     val dfltStm = (case init
135 : jhr 3909 of SOME v => let
136 :     (* get default file name for images and sequences *)
137 :     fun getName () = (case v
138 :     of IR.E_Lit(Literal.String s) => CL.mkStr s
139 :     | _ => raise Fail "expected string for default nrrd"
140 :     (* end case *))
141 :     in
142 : jhr 3911 case ty
143 : jhr 3910 of Ty.SeqTy(elemTy, NONE) =>
144 : jhr 3911 GenLoadNrrd.loadSeqFromFile (global var, elemTy, getName())
145 : jhr 3909 | Ty.ImageTy info =>
146 : jhr 3911 GenLoadNrrd.loadImage (global var, info, getName())
147 :     | _ => CL.mkBlock(ToC.trAssign(env, global var, v))
148 : jhr 3909 (* end case *)
149 :     end
150 :     | NONE => CL.mkBlock[
151 :     World.errorMsgAdd(CL.mkStr(concat["undefined input \"", name, "\"\n"])),
152 :     CL.mkReturn(SOME(CL.mkBool true))
153 :     ]
154 :     (* end case *))
155 :     in
156 :     CL.mkIfThen(CL.mkUnOp(CL.%!, U.defined gv), dfltStm)
157 :     end
158 :     in
159 :     CL.D_Func(
160 : jhr 3910 ["static"], CL.boolTy, N.checkDefined env,
161 : jhr 3909 [wrldParam],
162 :     CL.mkBlock(List.map check inputs @ [CL.mkReturn(SOME(CL.mkBool false))]))
163 :     end
164 :    
165 :     (* for each input variable we generate two or three top-level declarations in the
166 :     * exported API.
167 :     *)
168 :     fun genInputFuns (_, []) = []
169 : jhr 3910 | genInputFuns (env, inputs) = let
170 : jhr 3911 val spec = Env.target env
171 : jhr 3909 (* the world pointer type *)
172 : jhr 3910 val worldPtrTy = RN.worldPtrTy
173 : jhr 3909 val wrldParam = CL.PARAM([], worldPtrTy, "wrld")
174 :     (* create decls for an input variable *)
175 : jhr 3911 fun mkInputDecls (Inputs.INP{var, name, ty, desc, init}) = let
176 : jhr 3909 (* create a description declaration for the input variable *)
177 :     val descDcl = (case desc
178 :     of SOME desc => [
179 :     CL.D_Var([], CL.T_Ptr(CL.T_Named "const char"),
180 : jhr 3911 GenAPI.inputDesc(env, name),
181 : jhr 3909 SOME(CL.I_Exp(CL.mkStr desc)))
182 :     ]
183 :     | NONE => []
184 :     (* end case *))
185 :     val getDcl = if (Option.isSome optDflt)
186 :     then let
187 : jhr 3911 val getName = GenAPI.inputGet(spec, name)
188 : jhr 3909 (* generate code for a function that returns the current value of
189 :     * an input global.
190 :     *)
191 :     fun mkFunc outTy = CL.D_Func([], CL.voidTy, getName,
192 :     [wrldParam, CL.PARAM([], outTy, "v")],
193 :     CL.mkBlock(TrTy.copyToC{
194 :     ty = ty,
195 :     dst = (case outTy
196 :     of CL.T_Ptr _ => CL.mkUnOp(CL.%*, CL.mkVar "v")
197 :     | CL.T_Array _ => CL.mkVar "v"
198 :     | _ => raise Fail "not l-value type"
199 :     (* end cade *)),
200 : jhr 3911 src = global var
201 : jhr 3909 }))
202 :     (* FIXME: for images and sequences, it is not clear what the get function should return.
203 :     * For now, we just return 0
204 :     *)
205 :     (* for images and sequences, we currently return 0 *)
206 :     fun nrrdFunc () = CL.D_Func([], CL.voidTy, getName,
207 :     [wrldParam, CL.PARAM([], CL.T_Ptr CL.voidPtr, "v")],
208 :     CL.mkAssign(CL.mkUnOp(CL.%*, CL.mkVar "v"), CL.mkInt 0))
209 :     val func = (case ty
210 : jhr 3910 of Ty.BoolTy => mkFunc(CL.T_Ptr(trType(env, ty)))
211 :     | Ty.StringTy => mkFunc(CL.T_Ptr(trType(env, ty)))
212 :     | Ty.IntTy => mkFunc(CL.T_Ptr(trType(env, ty)))
213 :     | Ty.TensorTy[] => mkFunc(CL.T_Ptr(trType(env, ty)))
214 :     | Ty.TensorTy _ => mkFunc(trType(env, ty))
215 :     | Ty.SeqTy(_, SOME _) => mkFunc(trType(env, ty))
216 :     | Ty.SeqTy(_, NONE) => nrrdFunc ()
217 : jhr 3909 | Ty.ImageTy _ => nrrdFunc ()
218 :     | _ => raise Fail(concat["bogus input type ", Ty.toString ty])
219 :     (* end case *))
220 :     in
221 :     [func]
222 :     end
223 :     else []
224 :     val setDcl = (case ty
225 :     of Ty.ImageTy info => [
226 :     CL.D_Func(
227 : jhr 3911 [], CL.boolTy, GenAPI.inputSetByName(spec, name),
228 : jhr 3909 [wrldParam, CL.PARAM(["const"], CL.charPtr, "s")],
229 :     CL.appendStm(
230 : jhr 3911 GenLoadNrrd.loadImage (global var, info, CL.mkVar "s"),
231 : jhr 3909 CL.mkReturn(SOME(CL.mkBool false)))),
232 :     CL.D_Func(
233 : jhr 3911 [], CL.boolTy, GenAPI.inputSet(spec, name),
234 : jhr 3909 [wrldParam, CL.PARAM([], nrrdPtrTy, "nin")],
235 :     CL.appendStm(
236 : jhr 3911 GenLoadNrrd.setImage (global var, info, CL.mkVar "nin"),
237 : jhr 3909 CL.mkReturn(SOME(CL.mkBool false))))
238 :     ]
239 : jhr 3910 | Ty.SeqTy(elemTy, NONE) => [
240 : jhr 3909 CL.D_Func(
241 : jhr 3911 [], CL.boolTy, GenAPI.inputSetByName(spec, name),
242 : jhr 3909 [wrldParam, CL.PARAM(["const"], CL.charPtr, "s")],
243 :     CL.appendStm(
244 : jhr 3911 GenLoadNrrd.loadSeqFromFile (global var, elemTy, CL.mkVar "s"),
245 : jhr 3909 CL.mkReturn(SOME(CL.mkBool false)))),
246 :     CL.D_Func(
247 : jhr 3911 [], CL.boolTy, GenAPI.inputSet(spec, name),
248 : jhr 3909 [wrldParam, CL.PARAM([], nrrdPtrTy, "nin")],
249 :     CL.appendStm(
250 : jhr 3911 GenLoadNrrd.loadSeq (global var, elemTy, CL.mkVar "nin"),
251 : jhr 3909 CL.mkReturn(SOME(CL.mkBool false))))
252 :     ]
253 :     | _ => [
254 :     CL.D_Func(
255 : jhr 3911 [], CL.boolTy, GenAPI.inputSet(spec, name),
256 : jhr 3910 [wrldParam, CL.PARAM([], trType(env, ty), "v")],
257 : jhr 3909 CL.mkBlock(
258 : jhr 3911 CL.mkAssign(U.defined var, CL.mkBool true) ::
259 :     TrTy.copyFromC{ty=ty, dst=global var, src=CL.mkVar "v"} @
260 : jhr 3909 [CL.mkReturn(SOME(CL.mkVar "false"))]))
261 :     ]
262 :     (* end case *))
263 :     in
264 :     (descDcl @ getDcl @ setDcl)
265 :     end
266 :     val extras = [
267 : jhr 3910 genCheckInputs (env, inputs),
268 :     U.genDefineInp (env, inputs)
269 : jhr 3909 ]
270 :     in
271 :     List.foldr (fn (input, dcls) => mkInputDecls input @ dcls) extras inputs
272 :     end
273 :    
274 :     end

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