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

SCM Repository

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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1867 - (view) (download)

1 : jhr 1707 (* gen-output.sml
2 :     *
3 :     * COPYRIGHT (c) 2012 The Diderot Project (http://diderot-language.cs.uchicago.edu)
4 :     * All rights reserved.
5 :     *
6 : jhr 1792 * Generate strand output functions. The output formats always have a single axis for the
7 :     * data elements followed by one, or more, axes for the output structure. There are four
8 :     * cases that we handle:
9 : jhr 1710 *
10 :     * grid, fixed-size elements:
11 : jhr 1792 * nrrd has object axis followed by grid axes
12 : jhr 1710 *
13 :     * collection, fixed-size elements
14 : jhr 1792 * nrrd has object axis followed by a single axis
15 : jhr 1710 *
16 :     * grid, dynamic-size elements
17 : jhr 1792 * nLengths nrrd has size 2 for objects (offset, length) followed by grid axes
18 :     * nData nrrd has object axis followed by a single axis
19 : jhr 1710 *
20 :     * collection, dynamic-size elements
21 : jhr 1722 * nLengths nrrd has size 2 for objects (offset, length) followed by a single axis
22 : jhr 1792 * nData nrrd has object axis followed by a single axis
23 : jhr 1736 *
24 : jhr 1792 * The object axis kind depends on the output type, but it will either be one of the tensor types
25 :     * that Teem knows about or else nrrdKindList. In any case, the data elements are written as a
26 :     * flat vector following the in-memory layout. The other axes in the file will have nrrdKindSpace
27 :     * as their kind.
28 :     *
29 : jhr 1736 * TODO: some of this code will be common across all targets (e.g., writing outputs to files), so
30 :     * we will want to refactor it.
31 : jhr 1794 *
32 :     * TODO: for sequences of tensors (e.g., tensor[3]{2}), we should use a separate axis for the
33 :     * sequence dimension with kind nrrdKindList.
34 : jhr 1707 *)
35 :    
36 :     structure GenOutput : sig
37 :    
38 : jhr 1735 val gen : TargetUtil.target_desc * int option -> (TreeIL.Ty.ty * string) list -> CLang.decl list
39 : jhr 1707
40 :     end = struct
41 :    
42 :     structure IL = TreeIL
43 :     structure V = IL.Var
44 :     structure Ty = IL.Ty
45 :     structure CL = CLang
46 :     structure N = CNames
47 : jhr 1789 structure Nrrd = NrrdEnums
48 : jhr 1707
49 :     fun mapi f l = let
50 :     fun mapf (i, [], l) = List.rev l
51 :     | mapf (i, x::xs, l) = mapf (i+1, xs, f(i, x)::l)
52 :     in
53 :     mapf (0, l, [])
54 :     end
55 :    
56 :     val nrrdPtrTy = CL.T_Ptr(CL.T_Named "Nrrd")
57 : jhr 1736 val filePtrTy = CL.T_Ptr(CL.T_Named "FILE")
58 : jhr 1707 val sizeTy = CL.T_Named "size_t"
59 : jhr 1815 fun wrldPtr tgt = CL.T_Ptr(CL.T_Named(N.worldTy tgt))
60 : jhr 1707 fun mkInt i = CL.mkInt(IntInf.fromInt i)
61 :    
62 : jhr 1792 (* return information about the output type. This is a tuple
63 :     *
64 :     * (c-type, nrrd-type, nrrd-axis-kind, # elements)
65 :     *)
66 : jhr 1707 fun infoOf (tgt : TargetUtil.target_desc, ty) = (case ty
67 :     of Ty.IntTy => if #longint tgt
68 : jhr 1792 then (CL.int64, Nrrd.TypeLLong, Nrrd.KindScalar, 1)
69 :     else (CL.int32, Nrrd.TypeInt, Nrrd.KindScalar, 1)
70 : jhr 1707 | Ty.TensorTy [] => if #double tgt
71 : jhr 1792 then (CL.double, Nrrd.TypeDouble, Nrrd.KindScalar, 1)
72 :     else (CL.float, Nrrd.TypeFloat, Nrrd.KindScalar, 1)
73 :     | Ty.TensorTy dims => let
74 :     val (axisKind, nElems) = (case dims
75 :     of [2] => (Nrrd.Kind2Vector, 2)
76 :     | [3] => (Nrrd.Kind3Vector, 3)
77 :     | [4] => (Nrrd.Kind4Vector, 4)
78 :     | [2,2] => (Nrrd.Kind2DMatrix, 4)
79 :     | [3,3] => (Nrrd.Kind3DMatrix, 9)
80 :     | _ => (Nrrd.KindList, List.foldl Int.* 1 dims)
81 :     (* end case *))
82 :     in
83 :     if #double tgt
84 :     then (CL.double, Nrrd.TypeDouble, axisKind, nElems)
85 :     else (CL.float, Nrrd.TypeFloat, axisKind, nElems)
86 :     end
87 :     | Ty.SeqTy(ty, n) => raise Fail "FIXME" (*let
88 : jhr 1707 val (elemTy, nrrdTy, dims) = infoOf (tgt, ty)
89 :     in
90 :     (elemTy, nrrdTy, n::dims)
91 : jhr 1792 end*)
92 : jhr 1707 | _ => raise Fail(concat["GetOutput.infoOf(", Ty.toString ty, ")"])
93 :     (* end case *))
94 :    
95 :     (* variables in the generated code *)
96 :     val wrldV = CL.mkVar "wrld"
97 :     val sizesV = CL.mkVar "sizes"
98 :     val iV = CL.mkVar "i"
99 : jhr 1710 val nV = CL.mkVar "n"
100 : jhr 1715 val cpV = CL.mkVar "cp"
101 :     val ipV = CL.mkVar "ip"
102 : jhr 1710 val offsetV = CL.mkVar "offset"
103 : jhr 1722 val nDataV = CL.mkVar "nData"
104 :     val nLengthsV = CL.mkVar "nLengths"
105 : jhr 1708 val numStableV = CL.mkVar "numStable"
106 :     val numElemsV = CL.mkVar "numElems"
107 : jhr 1736 val outSV = CL.mkVar "outS"
108 : jhr 1707 val DIDEROT_STABLE = CL.mkVar "DIDEROT_STABLE"
109 : jhr 1708 val NRRD = CL.mkVar "NRRD"
110 : jhr 1707
111 : jhr 1708 (* dymanic sequence operations *)
112 :     fun seqLength arg = CL.mkApply("Diderot_DynSeqLength", [arg])
113 :     fun seqCopy (elemSz, dst, seq) = CL.mkApply("Diderot_DynSeqCopy", [elemSz, dst, seq])
114 :    
115 : jhr 1709 (* utility functions for initializing the sizes array *)
116 :     fun sizes i = CL.mkSubscript(sizesV, mkInt i)
117 :     fun setSizes (i, v) = CL.mkAssign(sizes i, v)
118 :    
119 : jhr 1708 (* code to access state variable
120 :     wrld->outState[i].name
121 :     *)
122 :     fun stateVar name = CL.mkIndirect(CL.mkSubscript(CL.mkIndirect(wrldV, "outState"), iV), name)
123 :    
124 :     (* code fragment to loop over strands
125 :     for (unsigned int i = 0; i < wrld->numStrands; i++) ...
126 :     *)
127 :     fun forStrands stm = CL.mkFor(
128 :     [(CL.uint32, "i", mkInt 0)],
129 :     CL.mkBinOp(iV, CL.#<, CL.mkIndirect(wrldV, "numStrands")),
130 : jhr 1718 [CL.mkPostOp(iV, CL.^++)],
131 : jhr 1708 stm)
132 :    
133 :     (* code fragment to test for stable strands in a loop
134 :     if (wrld->status[i] == DIDEROT_STABLE)
135 :     ...
136 :     *)
137 :     fun ifStable stm = CL.mkIfThen(
138 :     CL.mkBinOp(CL.mkSubscript(CL.mkIndirect(wrldV, "status"), iV), CL.#==, DIDEROT_STABLE),
139 :     stm)
140 :    
141 :     (* code fragment to allocate nrrd data and check for errors
142 :     if (nrrdMaybeAlloc_nva(<nrrdVar>, <nrrdType>, <nDims>, sizes) != 0) {
143 : jhr 1862 char *msg = biffGetDone(NRRD);
144 :     biffMsgAdd (wrld->errors, msg);
145 :     FREE (msg);
146 : jhr 1708 return true;
147 : jhr 1707 }
148 : jhr 1708 *)
149 :     fun maybeAlloc (nrrdVar, nrrdType, nDims) =
150 :     CL.mkIfThen(
151 :     CL.mkBinOp(
152 :     CL.mkApply("nrrdMaybeAlloc_nva", [
153 :     nrrdVar, CL.mkVar nrrdType, mkInt nDims, sizesV
154 :     ]),
155 :     CL.#!=,
156 :     CL.mkInt 0),
157 :     (* then *)
158 :     CL.mkBlock[
159 : jhr 1862 CL.mkDeclInit(CL.charPtr, "msg", CL.mkApply("biffGetDone", [NRRD])),
160 :     CL.mkCall("biffMsgAdd", [CL.mkIndirect(wrldV, "errors"), CL.mkVar "msg"]),
161 :     CL.mkCall("FREE", [CL.mkVar "msg"]),
162 : jhr 1708 CL.mkReturn(SOME(CL.mkVar "true"))
163 :     ]
164 :     (* endif*))
165 : jhr 1707
166 : jhr 1799 (* code fragment to initialize the axes kinds; the data axis (axis[0]) is given, but we skip it
167 :     * (by convention) if it is scalar. The other axes are always KindSpace.
168 :     *)
169 : jhr 1792 fun initAxisKinds (nrrd, dataAxisKind, nAxes) = let
170 :     (* nData->axis[0].kind *)
171 :     fun axisKind i = CL.mkSelect(CL.mkSubscript(CL.mkIndirect(nrrd, "axis"), mkInt i), "kind")
172 :     fun init (i, k) = CL.mkAssign (axisKind i, CL.mkVar(Nrrd.kindToEnum k))
173 : jhr 1799 val (firstSpace, dataAxis) = (case dataAxisKind
174 :     of Nrrd.KindScalar => (0, [])
175 :     | _ => (1, [init(0, dataAxisKind)])
176 :     (* end case *))
177 : jhr 1792 in
178 : jhr 1799 dataAxis @ List.tabulate(nAxes, fn i => init(i+firstSpace, Nrrd.KindSpace))
179 : jhr 1792 end
180 :    
181 : jhr 1708 (* create the body of an output function for dynamic-size outputs. The structure of the
182 :     * function body is:
183 :     *
184 :     * declarations
185 : jhr 1722 * compute sizes array for nLengths
186 :     * allocate nrrd for nLengths
187 :     * compute sizes array for nData
188 :     * allocate nrrd for nData
189 : jhr 1708 * copy data from strands to nrrd
190 :     *)
191 :     fun genDynOutput (tgt, nAxes, ty, name) = let
192 : jhr 1792 val (elemCTy, nrrdType, axisKind, nElems) = infoOf (tgt, ty)
193 : jhr 1708 val (isArray, nAxes) = (case nAxes of NONE => (false, 1) | SOME n => (true, n))
194 :     (* declarations *)
195 : jhr 1792 val sizesDecl = CL.mkDecl(CL.T_Array(sizeTy, SOME(nAxes+1)), "sizes", NONE)
196 : jhr 1708 (* count number of elements (and stable strands) *)
197 :     val countElems = let
198 : jhr 1715 val nElemsInit = CL.mkDeclInit(CL.uint32, "numElems", CL.mkInt 0)
199 : jhr 1708 val cntElems = CL.S_Exp(CL.mkAssignOp(numElemsV, CL.+=, seqLength(stateVar name)))
200 :     in
201 :     if isArray
202 :     then [
203 :     CL.mkComment["count number of elements"],
204 :     nElemsInit, forStrands cntElems
205 :     ]
206 :     else [
207 : jhr 1710 CL.mkComment["count number of output elements and stable strands"],
208 : jhr 1715 CL.mkDeclInit(CL.uint32, "numStable", CL.mkInt 0),
209 :     nElemsInit,
210 : jhr 1708 forStrands(ifStable(CL.mkBlock[cntElems, CL.S_Exp(CL.mkPostOp(numStableV, CL.^++))]))
211 :     ]
212 :     end
213 : jhr 1722 (* generate code to allocate the nLengths nrrd *)
214 : jhr 1708 val lengthsNrrd = let
215 : jhr 1722 val dimSizes = setSizes(0, CL.mkInt 2) (* nLengths is 2-element vector *)
216 : jhr 1708 in
217 : jhr 1722 CL.mkComment["allocate nLengths nrrd"] ::
218 : jhr 1709 (if isArray
219 : jhr 1708 then dimSizes ::
220 :     List.tabulate (nAxes, fn i =>
221 : jhr 1718 setSizes(i+1, CL.mkSubscript(CL.mkIndirect(wrldV, "size"), mkInt(nAxes-i-1)))) @
222 : jhr 1789 [maybeAlloc (nLengthsV, Nrrd.tyToEnum Nrrd.TypeInt, nAxes+1)]
223 : jhr 1708 else [
224 : jhr 1792 dimSizes, setSizes(1, numStableV),
225 : jhr 1789 maybeAlloc (nLengthsV, Nrrd.tyToEnum Nrrd.TypeInt, 2)
226 : jhr 1709 ])
227 : jhr 1708 end
228 : jhr 1709 (* generate code to allocate the data nrrd *)
229 : jhr 1799 val dataNrrd = if (axisKind = Nrrd.KindScalar)
230 :     then [ (* drop data axis for scalar data by convention *)
231 :     CL.mkComment["allocate nData nrrd"],
232 :     setSizes(0, numElemsV),
233 :     maybeAlloc (nDataV, Nrrd.tyToEnum nrrdType, 1)
234 :     ]
235 :     else [
236 :     CL.mkComment["allocate nData nrrd"],
237 :     setSizes(0, mkInt nElems),
238 :     setSizes(1, numElemsV),
239 :     maybeAlloc (nDataV, Nrrd.tyToEnum nrrdType, 2)
240 :     ]
241 : jhr 1722 (* generate the nLengths copy code *)
242 : jhr 1709 val copyLengths = let
243 : jhr 1715 val pInit = CL.mkDeclInit(CL.T_Ptr CL.uint32, "ip",
244 : jhr 1722 CL.mkCast(CL.T_Ptr(CL.uint32), CL.mkIndirect(nLengthsV, "data")))
245 : jhr 1715 val offsetDecl = CL.mkDeclInit(CL.uint32, "offset", CL.mkInt 0)
246 : jhr 1710 val copyBlk = CL.mkBlock[
247 : jhr 1715 CL.mkDeclInit(CL.uint32, "n", seqLength(stateVar name)),
248 :     CL.mkAssign(CL.mkUnOp(CL.%*, CL.mkPostOp(ipV, CL.^++)), offsetV),
249 :     CL.mkAssign(CL.mkUnOp(CL.%*, CL.mkPostOp(ipV, CL.^++)), nV),
250 : jhr 1710 CL.S_Exp(CL.mkAssignOp(offsetV, CL.+=, nV))
251 :     ]
252 :     val copyStm = if isArray
253 :     then copyBlk
254 :     else ifStable copyBlk
255 : jhr 1709 in
256 : jhr 1792 CL.mkComment["initialize nLengths nrrd"] ::
257 :     pInit ::
258 :     offsetDecl ::
259 :     forStrands copyStm ::
260 :     initAxisKinds (nLengthsV, Nrrd.Kind2Vector, nAxes)
261 : jhr 1709 end
262 : jhr 1722 (* generate the nData copy code *)
263 : jhr 1709 val copyData = let
264 : jhr 1715 val pInit = CL.mkDeclInit(CL.charPtr, "cp",
265 : jhr 1722 CL.mkCast(CL.charPtr, CL.mkIndirect(nDataV, "data")))
266 : jhr 1715 val copyStm = CL.mkAssign(cpV, seqCopy(
267 :     CL.mkBinOp(mkInt nElems, CL.#*, CL.mkSizeof(elemCTy)), cpV, stateVar name))
268 : jhr 1710 val copyStm = if isArray
269 :     then copyStm
270 :     else ifStable copyStm
271 : jhr 1709 in
272 : jhr 1792 CL.mkComment["initialize nLengths nrrd"] ::
273 :     pInit ::
274 :     forStrands copyStm ::
275 :     initAxisKinds (nDataV, axisKind, 1)
276 : jhr 1709 end
277 : jhr 1708 (* the function body *)
278 :     val stms =
279 : jhr 1715 sizesDecl ::
280 : jhr 1708 countElems @
281 :     lengthsNrrd @
282 :     dataNrrd @
283 :     copyLengths @
284 :     copyData @
285 :     [CL.mkReturn(SOME(CL.mkVar "false"))]
286 :     in
287 : jhr 1722 ([CL.PARAM([], nrrdPtrTy, "nLengths"), CL.PARAM([], nrrdPtrTy, "nData")], CL.mkBlock stms)
288 : jhr 1708 end
289 : jhr 1707
290 :     (* create the body of an output function for fixed-size outputs. The structure of the
291 :     * function body is:
292 :     *
293 :     * declare and compute sizes array
294 : jhr 1722 * allocate nrrd nData
295 : jhr 1707 * copy data from strands to nrrd
296 :     *)
297 :     fun genFixedOutput (tgt, nAxes, ty, name) = let
298 : jhr 1792 val (elemCTy, nrrdType, axisKind, nElems) = infoOf (tgt, ty)
299 : jhr 1707 val (isArray, nAxes) = (case nAxes of NONE => (false, 1) | SOME n => (true, n))
300 : jhr 1799 val nDataAxes = if (axisKind = Nrrd.KindScalar) then 0 else 1
301 : jhr 1707 (* generate the sizes initialization code *)
302 :     val initSizes = let
303 : jhr 1799 val dimSizes = let
304 :     val dcl = CL.mkDecl(CL.T_Array(sizeTy, SOME(nAxes+nDataAxes)), "sizes", NONE)
305 :     in
306 :     if (axisKind = Nrrd.KindScalar)
307 :     then [dcl]
308 :     else [dcl, setSizes(0, mkInt nElems)]
309 :     end
310 : jhr 1707 in
311 :     if isArray
312 :     then dimSizes @
313 :     List.tabulate (nAxes, fn i =>
314 : jhr 1799 setSizes(i+nDataAxes, CL.mkSubscript(CL.mkIndirect(wrldV, "size"), mkInt(nAxes-i-1))))
315 : jhr 1708 else
316 : jhr 1715 CL.mkDeclInit(sizeTy, "numStable", mkInt 0) ::
317 : jhr 1708 forStrands (ifStable(CL.S_Exp(CL.mkPostOp(numStableV, CL.^++)))) ::
318 : jhr 1799 dimSizes @ [setSizes(nDataAxes, numStableV)]
319 : jhr 1707 end
320 :     (* generate the copy code *)
321 :     val copyCode = let
322 : jhr 1715 val pDecl = CL.mkDeclInit(CL.charPtr, "cp",
323 : jhr 1722 CL.mkCast(CL.charPtr, CL.mkIndirect(nDataV, "data")))
324 : jhr 1711 val copyBlk = CL.mkBlock[
325 : jhr 1707 CL.mkCall("memcpy", [
326 : jhr 1715 cpV,
327 : jhr 1708 CL.mkUnOp(CL.%&, stateVar name),
328 : jhr 1734 CL.mkBinOp(mkInt nElems, CL.#*, CL.mkSizeof elemCTy)
329 : jhr 1707 ]),
330 : jhr 1734 CL.mkExpStm(CL.mkAssignOp(cpV, CL.+=,
331 :     CL.mkBinOp(mkInt nElems, CL.#*, CL.mkSizeof elemCTy)))
332 : jhr 1707 ]
333 : jhr 1711 val copyStm = if isArray
334 :     then copyBlk
335 :     else ifStable copyBlk
336 : jhr 1707 in
337 : jhr 1792 pDecl :: forStrands copyStm :: initAxisKinds (nDataV, axisKind, nAxes)
338 : jhr 1707 end
339 :     (* the function body *)
340 :     val stms =
341 :     CL.mkComment["Compute sizes of nrrd file"] ::
342 :     initSizes @
343 : jhr 1722 CL.mkComment["Allocate nData nrrd"] ::
344 : jhr 1799 maybeAlloc (nDataV, Nrrd.tyToEnum nrrdType, nAxes+nDataAxes) ::
345 : jhr 1707 CL.mkComment["copy data to output nrrd"] ::
346 :     copyCode @
347 : jhr 1708 [CL.mkReturn(SOME(CL.mkVar "false"))]
348 : jhr 1707 in
349 : jhr 1722 ([CL.PARAM([], nrrdPtrTy, "nData")], CL.mkBlock stms)
350 : jhr 1707 end
351 :    
352 : jhr 1735 (* generate the nrrd-file output and print functions used by standalone executables *)
353 :     fun genOutput (tgt : TargetUtil.target_desc, outputs) = let
354 :     fun isDyn ty = (case ty of Ty.DynSeqTy _ => true | _ => false)
355 : jhr 1862 (* FIXME: use biffMsgAddF and return error status *)
356 : jhr 1735 fun error (fmt, msg) = CL.mkBlock[
357 :     CL.mkCall("fprintf", [CL.mkVar "stderr", CL.mkStr fmt, msg]),
358 :     CL.mkCall("exit", [CL.mkInt 1])
359 :     ]
360 : jhr 1736 val outDecls = if List.exists (isDyn o #1) outputs
361 : jhr 1735 then [CL.mkDecl(nrrdPtrTy, "nLengths", NONE), CL.mkDecl(nrrdPtrTy, "nData", NONE)]
362 :     else [CL.mkDecl(nrrdPtrTy, "nData", NONE)]
363 : jhr 1736 val prDecls = outDecls @ [CL.mkDecl(filePtrTy, "outS", NONE)]
364 : jhr 1735 fun nrrdNew v = CL.mkAssign(v, CL.mkApply("nrrdNew", []))
365 :     fun nrrdNuke v = CL.mkCall("nrrdNuke", [v])
366 :     fun writeNrrd (ty, name) =
367 :     if isDyn ty
368 :     then [
369 :     nrrdNew (nLengthsV),
370 :     nrrdNew (nDataV),
371 :     CL.mkIfThenElse(
372 : jhr 1815 CL.mkApply(N.outputGet(tgt, name), [wrldV, nLengthsV, nDataV]),
373 : jhr 1735 (* then *)
374 : nseltzer 1867 error ("Error getting nrrd data: %s\n", CL.mkApply("biffMsgStrGet", [CL.mkIndirect(wrldV, "errors")])),
375 : jhr 1735 (* else *)
376 :     CL.mkIfThen(
377 :     CL.mkBinOp(
378 :     CL.mkApply("nrrdSave", [
379 :     CL.mkStr(OS.Path.joinBaseExt{base=name^"-len", ext=SOME "nrrd"}),
380 :     nLengthsV, CL.mkVar "NULL"
381 :     ]),
382 :     CL.#||,
383 :     CL.mkApply("nrrdSave", [
384 :     CL.mkStr(OS.Path.joinBaseExt{base=name^"-data", ext=SOME "nrrd"}),
385 :     nDataV, CL.mkVar "NULL"
386 :     ])),
387 :     (* then *)
388 :     error ("Error saving nrrd: %s\n", CL.mkApply("biffGetDone", [NRRD]))
389 :     (* endif *))
390 :     (* endif *)),
391 :     nrrdNuke nLengthsV,
392 :     nrrdNuke nDataV
393 :     ]
394 :     else [
395 :     nrrdNew (nDataV),
396 :     CL.mkIfThenElse(
397 : jhr 1815 CL.mkApply(N.outputGet(tgt, name), [wrldV, nDataV]),
398 : jhr 1735 (* then *)
399 : nseltzer 1867 error ("Error getting nrrd data: %s\n", CL.mkApply("biffMsgStrGet", [CL.mkIndirect(wrldV, "errors")])),
400 : jhr 1735 (* else *)
401 :     CL.mkIfThen(
402 :     CL.mkApply("nrrdSave", [
403 :     CL.mkStr(OS.Path.joinBaseExt{base=name, ext=SOME "nrrd"}),
404 :     nDataV, CL.mkVar "NULL"
405 :     ]),
406 :     (* then *)
407 :     error ("Error saving nrrd: %s\n", CL.mkApply("biffGetDone", [NRRD]))
408 :     (* endif *))
409 :     (* endif *)),
410 :     nrrdNuke nDataV
411 :     ]
412 : jhr 1736 fun printNrrd (ty, name) = [] (* FIXME *)
413 : jhr 1735 in [
414 :     CL.D_Func(["static"], CL.voidTy, "WriteOutput", [CL.PARAM([], wrldPtr tgt, "wrld")],
415 : jhr 1736 CL.mkBlock(outDecls @ List.foldr (fn (output, l) => writeNrrd output @ l) [] outputs)),
416 :     CL.D_Func(["static"], CL.voidTy, "PrintOutput", [CL.PARAM([], wrldPtr tgt, "wrld")],
417 :     CL.mkBlock(prDecls @ List.foldr (fn (output, l) => printNrrd output @ l) [] outputs))
418 : jhr 1735 ] end
419 :    
420 :     fun gen (tgt : TargetUtil.target_desc, nAxes) = let
421 :     fun getFn (ty, name) = let
422 : jhr 1815 val funcName = N.outputGet(tgt, name)
423 : jhr 1735 fun mkFunc (params, body) =
424 :     CL.D_Func([], CL.boolTy, funcName, CL.PARAM([], wrldPtr tgt, "wrld")::params, body)
425 :     in
426 :     case ty
427 :     of Ty.DynSeqTy ty' => mkFunc (genDynOutput(tgt, nAxes, ty', name))
428 :     | _ => mkFunc (genFixedOutput(tgt, nAxes, ty, name))
429 :     (* end case *)
430 :     end
431 :     fun gen' outputs = let
432 :     val getFns = List.map getFn outputs
433 :     in
434 :     if (#exec tgt)
435 :     then getFns @ genOutput(tgt, outputs)
436 :     else getFns
437 :     end
438 : jhr 1707 in
439 : jhr 1735 gen'
440 : jhr 1707 end
441 :    
442 :     end

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