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

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