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 1912 - (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 1872 val msgV = CL.mkVar "msg"
103 : jhr 1710 val offsetV = CL.mkVar "offset"
104 : jhr 1722 val nDataV = CL.mkVar "nData"
105 :     val nLengthsV = CL.mkVar "nLengths"
106 : jhr 1708 val numStableV = CL.mkVar "numStable"
107 :     val numElemsV = CL.mkVar "numElems"
108 : jhr 1736 val outSV = CL.mkVar "outS"
109 : jhr 1912 val DIDEROT_DIE = CL.mkVar "DIDEROT_DIE"
110 : jhr 1707 val DIDEROT_STABLE = CL.mkVar "DIDEROT_STABLE"
111 : jhr 1708 val NRRD = CL.mkVar "NRRD"
112 : jhr 1707
113 : jhr 1708 (* dymanic sequence operations *)
114 :     fun seqLength arg = CL.mkApply("Diderot_DynSeqLength", [arg])
115 :     fun seqCopy (elemSz, dst, seq) = CL.mkApply("Diderot_DynSeqCopy", [elemSz, dst, seq])
116 :    
117 : jhr 1709 (* utility functions for initializing the sizes array *)
118 :     fun sizes i = CL.mkSubscript(sizesV, mkInt i)
119 :     fun setSizes (i, v) = CL.mkAssign(sizes i, v)
120 :    
121 : jhr 1708 (* code to access state variable
122 :     wrld->outState[i].name
123 :     *)
124 :     fun stateVar name = CL.mkIndirect(CL.mkSubscript(CL.mkIndirect(wrldV, "outState"), iV), name)
125 :    
126 :     (* code fragment to loop over strands
127 :     for (unsigned int i = 0; i < wrld->numStrands; i++) ...
128 :     *)
129 :     fun forStrands stm = CL.mkFor(
130 :     [(CL.uint32, "i", mkInt 0)],
131 :     CL.mkBinOp(iV, CL.#<, CL.mkIndirect(wrldV, "numStrands")),
132 : jhr 1718 [CL.mkPostOp(iV, CL.^++)],
133 : jhr 1708 stm)
134 :    
135 :     (* code fragment to test for stable strands in a loop
136 :     if (wrld->status[i] == DIDEROT_STABLE)
137 :     ...
138 :     *)
139 :     fun ifStable stm = CL.mkIfThen(
140 :     CL.mkBinOp(CL.mkSubscript(CL.mkIndirect(wrldV, "status"), iV), CL.#==, DIDEROT_STABLE),
141 :     stm)
142 :    
143 : jhr 1912 (* code fragment to test for active strands in a loop; note that NEW strands are considered active.
144 :     if (wrld->status[i] != DIDEROT_DIE)
145 :     ...
146 :     *)
147 :     fun ifActive stm = CL.mkIfThen(
148 :     CL.mkBinOp(CL.mkSubscript(CL.mkIndirect(wrldV, "status"), iV), CL.#!=, DIDEROT_DIE),
149 :     stm)
150 :    
151 : jhr 1708 (* code fragment to allocate nrrd data and check for errors
152 :     if (nrrdMaybeAlloc_nva(<nrrdVar>, <nrrdType>, <nDims>, sizes) != 0) {
153 : jhr 1862 char *msg = biffGetDone(NRRD);
154 :     biffMsgAdd (wrld->errors, msg);
155 :     FREE (msg);
156 : jhr 1708 return true;
157 : jhr 1707 }
158 : jhr 1708 *)
159 :     fun maybeAlloc (nrrdVar, nrrdType, nDims) =
160 :     CL.mkIfThen(
161 :     CL.mkBinOp(
162 :     CL.mkApply("nrrdMaybeAlloc_nva", [
163 :     nrrdVar, CL.mkVar nrrdType, mkInt nDims, sizesV
164 :     ]),
165 :     CL.#!=,
166 :     CL.mkInt 0),
167 :     (* then *)
168 :     CL.mkBlock[
169 : jhr 1862 CL.mkDeclInit(CL.charPtr, "msg", CL.mkApply("biffGetDone", [NRRD])),
170 : jhr 1872 CL.mkCall("biffMsgAdd", [CL.mkIndirect(wrldV, "errors"), msgV]),
171 :     CL.mkCall("FREE", [msgV]),
172 : jhr 1708 CL.mkReturn(SOME(CL.mkVar "true"))
173 :     ]
174 :     (* endif*))
175 : jhr 1707
176 : jhr 1799 (* code fragment to initialize the axes kinds; the data axis (axis[0]) is given, but we skip it
177 :     * (by convention) if it is scalar. The other axes are always KindSpace.
178 :     *)
179 : jhr 1792 fun initAxisKinds (nrrd, dataAxisKind, nAxes) = let
180 :     (* nData->axis[0].kind *)
181 :     fun axisKind i = CL.mkSelect(CL.mkSubscript(CL.mkIndirect(nrrd, "axis"), mkInt i), "kind")
182 :     fun init (i, k) = CL.mkAssign (axisKind i, CL.mkVar(Nrrd.kindToEnum k))
183 : jhr 1799 val (firstSpace, dataAxis) = (case dataAxisKind
184 :     of Nrrd.KindScalar => (0, [])
185 :     | _ => (1, [init(0, dataAxisKind)])
186 :     (* end case *))
187 : jhr 1792 in
188 : jhr 1799 dataAxis @ List.tabulate(nAxes, fn i => init(i+firstSpace, Nrrd.KindSpace))
189 : jhr 1792 end
190 :    
191 : jhr 1708 (* create the body of an output function for dynamic-size outputs. The structure of the
192 :     * function body is:
193 :     *
194 :     * declarations
195 : jhr 1722 * compute sizes array for nLengths
196 :     * allocate nrrd for nLengths
197 :     * compute sizes array for nData
198 :     * allocate nrrd for nData
199 : jhr 1708 * copy data from strands to nrrd
200 :     *)
201 : jhr 1912 fun genDynOutput (tgt, snapshot, nAxes, ty, name) = let
202 : jhr 1792 val (elemCTy, nrrdType, axisKind, nElems) = infoOf (tgt, ty)
203 : jhr 1708 val (isArray, nAxes) = (case nAxes of NONE => (false, 1) | SOME n => (true, n))
204 :     (* declarations *)
205 : jhr 1792 val sizesDecl = CL.mkDecl(CL.T_Array(sizeTy, SOME(nAxes+1)), "sizes", NONE)
206 : jhr 1708 (* count number of elements (and stable strands) *)
207 :     val countElems = let
208 : jhr 1715 val nElemsInit = CL.mkDeclInit(CL.uint32, "numElems", CL.mkInt 0)
209 : jhr 1708 val cntElems = CL.S_Exp(CL.mkAssignOp(numElemsV, CL.+=, seqLength(stateVar name)))
210 :     in
211 :     if isArray
212 :     then [
213 :     CL.mkComment["count number of elements"],
214 :     nElemsInit, forStrands cntElems
215 :     ]
216 : jhr 1912 else let
217 :     val cntBlk = CL.mkBlock[cntElems, CL.S_Exp(CL.mkPostOp(numStableV, CL.^++))]
218 :     val lpBody = if snapshot
219 :     then ifActive cntBlk
220 :     else ifStable cntBlk
221 :     in [
222 : jhr 1710 CL.mkComment["count number of output elements and stable strands"],
223 : jhr 1715 CL.mkDeclInit(CL.uint32, "numStable", CL.mkInt 0),
224 :     nElemsInit,
225 : jhr 1912 forStrands lpBody
226 :     ] end
227 : jhr 1708 end
228 : jhr 1722 (* generate code to allocate the nLengths nrrd *)
229 : jhr 1708 val lengthsNrrd = let
230 : jhr 1722 val dimSizes = setSizes(0, CL.mkInt 2) (* nLengths is 2-element vector *)
231 : jhr 1708 in
232 : jhr 1722 CL.mkComment["allocate nLengths nrrd"] ::
233 : jhr 1709 (if isArray
234 : jhr 1708 then dimSizes ::
235 :     List.tabulate (nAxes, fn i =>
236 : jhr 1718 setSizes(i+1, CL.mkSubscript(CL.mkIndirect(wrldV, "size"), mkInt(nAxes-i-1)))) @
237 : jhr 1789 [maybeAlloc (nLengthsV, Nrrd.tyToEnum Nrrd.TypeInt, nAxes+1)]
238 : jhr 1708 else [
239 : jhr 1792 dimSizes, setSizes(1, numStableV),
240 : jhr 1789 maybeAlloc (nLengthsV, Nrrd.tyToEnum Nrrd.TypeInt, 2)
241 : jhr 1709 ])
242 : jhr 1708 end
243 : jhr 1709 (* generate code to allocate the data nrrd *)
244 : jhr 1799 val dataNrrd = if (axisKind = Nrrd.KindScalar)
245 :     then [ (* drop data axis for scalar data by convention *)
246 :     CL.mkComment["allocate nData nrrd"],
247 :     setSizes(0, numElemsV),
248 :     maybeAlloc (nDataV, Nrrd.tyToEnum nrrdType, 1)
249 :     ]
250 :     else [
251 :     CL.mkComment["allocate nData nrrd"],
252 :     setSizes(0, mkInt nElems),
253 :     setSizes(1, numElemsV),
254 :     maybeAlloc (nDataV, Nrrd.tyToEnum nrrdType, 2)
255 :     ]
256 : jhr 1722 (* generate the nLengths copy code *)
257 : jhr 1709 val copyLengths = let
258 : jhr 1715 val pInit = CL.mkDeclInit(CL.T_Ptr CL.uint32, "ip",
259 : jhr 1722 CL.mkCast(CL.T_Ptr(CL.uint32), CL.mkIndirect(nLengthsV, "data")))
260 : jhr 1715 val offsetDecl = CL.mkDeclInit(CL.uint32, "offset", CL.mkInt 0)
261 : jhr 1710 val copyBlk = CL.mkBlock[
262 : jhr 1715 CL.mkDeclInit(CL.uint32, "n", seqLength(stateVar name)),
263 :     CL.mkAssign(CL.mkUnOp(CL.%*, CL.mkPostOp(ipV, CL.^++)), offsetV),
264 :     CL.mkAssign(CL.mkUnOp(CL.%*, CL.mkPostOp(ipV, CL.^++)), nV),
265 : jhr 1710 CL.S_Exp(CL.mkAssignOp(offsetV, CL.+=, nV))
266 :     ]
267 :     val copyStm = if isArray
268 :     then copyBlk
269 : jhr 1912 else if #snapshot tgt
270 :     then ifActive copyBlk
271 :     else ifStable copyBlk
272 : jhr 1709 in
273 : jhr 1792 CL.mkComment["initialize nLengths nrrd"] ::
274 :     pInit ::
275 :     offsetDecl ::
276 :     forStrands copyStm ::
277 :     initAxisKinds (nLengthsV, Nrrd.Kind2Vector, nAxes)
278 : jhr 1709 end
279 : jhr 1722 (* generate the nData copy code *)
280 : jhr 1709 val copyData = let
281 : jhr 1715 val pInit = CL.mkDeclInit(CL.charPtr, "cp",
282 : jhr 1722 CL.mkCast(CL.charPtr, CL.mkIndirect(nDataV, "data")))
283 : jhr 1715 val copyStm = CL.mkAssign(cpV, seqCopy(
284 :     CL.mkBinOp(mkInt nElems, CL.#*, CL.mkSizeof(elemCTy)), cpV, stateVar name))
285 : jhr 1710 val copyStm = if isArray
286 : jhr 1912 then copyStm
287 :     else if #snapshot tgt
288 :     then ifActive copyStm
289 :     else ifStable copyStm
290 : jhr 1709 in
291 : jhr 1792 CL.mkComment["initialize nLengths nrrd"] ::
292 :     pInit ::
293 :     forStrands copyStm ::
294 :     initAxisKinds (nDataV, axisKind, 1)
295 : jhr 1709 end
296 : jhr 1708 (* the function body *)
297 :     val stms =
298 : jhr 1715 sizesDecl ::
299 : jhr 1708 countElems @
300 :     lengthsNrrd @
301 :     dataNrrd @
302 :     copyLengths @
303 :     copyData @
304 :     [CL.mkReturn(SOME(CL.mkVar "false"))]
305 :     in
306 : jhr 1722 ([CL.PARAM([], nrrdPtrTy, "nLengths"), CL.PARAM([], nrrdPtrTy, "nData")], CL.mkBlock stms)
307 : jhr 1708 end
308 : jhr 1707
309 :     (* create the body of an output function for fixed-size outputs. The structure of the
310 :     * function body is:
311 :     *
312 :     * declare and compute sizes array
313 : jhr 1722 * allocate nrrd nData
314 : jhr 1707 * copy data from strands to nrrd
315 :     *)
316 : jhr 1912 fun genFixedOutput (tgt, snapshot, nAxes, ty, name) = let
317 : jhr 1792 val (elemCTy, nrrdType, axisKind, nElems) = infoOf (tgt, ty)
318 : jhr 1707 val (isArray, nAxes) = (case nAxes of NONE => (false, 1) | SOME n => (true, n))
319 : jhr 1799 val nDataAxes = if (axisKind = Nrrd.KindScalar) then 0 else 1
320 : jhr 1707 (* generate the sizes initialization code *)
321 :     val initSizes = let
322 : jhr 1799 val dimSizes = let
323 :     val dcl = CL.mkDecl(CL.T_Array(sizeTy, SOME(nAxes+nDataAxes)), "sizes", NONE)
324 :     in
325 :     if (axisKind = Nrrd.KindScalar)
326 :     then [dcl]
327 :     else [dcl, setSizes(0, mkInt nElems)]
328 :     end
329 : jhr 1707 in
330 :     if isArray
331 :     then dimSizes @
332 :     List.tabulate (nAxes, fn i =>
333 : jhr 1799 setSizes(i+nDataAxes, CL.mkSubscript(CL.mkIndirect(wrldV, "size"), mkInt(nAxes-i-1))))
334 : jhr 1912 else let
335 :     val cntStm = CL.S_Exp(CL.mkPostOp(numStableV, CL.^++))
336 :     val lpBody = if snapshot
337 :     then ifActive cntStm
338 :     else ifStable cntStm
339 :     in
340 :     CL.mkDeclInit(sizeTy, "numStable", mkInt 0) ::
341 :     forStrands lpBody ::
342 :     dimSizes @ [setSizes(nDataAxes, numStableV)]
343 :     end
344 : jhr 1707 end
345 :     (* generate the copy code *)
346 :     val copyCode = let
347 : jhr 1715 val pDecl = CL.mkDeclInit(CL.charPtr, "cp",
348 : jhr 1722 CL.mkCast(CL.charPtr, CL.mkIndirect(nDataV, "data")))
349 : jhr 1711 val copyBlk = CL.mkBlock[
350 : jhr 1707 CL.mkCall("memcpy", [
351 : jhr 1715 cpV,
352 : jhr 1708 CL.mkUnOp(CL.%&, stateVar name),
353 : jhr 1734 CL.mkBinOp(mkInt nElems, CL.#*, CL.mkSizeof elemCTy)
354 : jhr 1707 ]),
355 : jhr 1734 CL.mkExpStm(CL.mkAssignOp(cpV, CL.+=,
356 :     CL.mkBinOp(mkInt nElems, CL.#*, CL.mkSizeof elemCTy)))
357 : jhr 1707 ]
358 : jhr 1711 val copyStm = if isArray
359 : jhr 1912 then copyBlk
360 :     else if #snapshot tgt
361 :     then ifActive copyBlk
362 :     else ifStable copyBlk
363 : jhr 1707 in
364 : jhr 1792 pDecl :: forStrands copyStm :: initAxisKinds (nDataV, axisKind, nAxes)
365 : jhr 1707 end
366 :     (* the function body *)
367 :     val stms =
368 :     CL.mkComment["Compute sizes of nrrd file"] ::
369 :     initSizes @
370 : jhr 1722 CL.mkComment["Allocate nData nrrd"] ::
371 : jhr 1799 maybeAlloc (nDataV, Nrrd.tyToEnum nrrdType, nAxes+nDataAxes) ::
372 : jhr 1707 CL.mkComment["copy data to output nrrd"] ::
373 :     copyCode @
374 : jhr 1708 [CL.mkReturn(SOME(CL.mkVar "false"))]
375 : jhr 1707 in
376 : jhr 1722 ([CL.PARAM([], nrrdPtrTy, "nData")], CL.mkBlock stms)
377 : jhr 1707 end
378 :    
379 : jhr 1735 (* generate the nrrd-file output and print functions used by standalone executables *)
380 :     fun genOutput (tgt : TargetUtil.target_desc, outputs) = let
381 :     fun isDyn ty = (case ty of Ty.DynSeqTy _ => true | _ => false)
382 : jhr 1862 (* FIXME: use biffMsgAddF and return error status *)
383 : jhr 1735 fun error (fmt, msg) = CL.mkBlock[
384 :     CL.mkCall("fprintf", [CL.mkVar "stderr", CL.mkStr fmt, msg]),
385 :     CL.mkCall("exit", [CL.mkInt 1])
386 :     ]
387 : jhr 1736 val outDecls = if List.exists (isDyn o #1) outputs
388 : jhr 1735 then [CL.mkDecl(nrrdPtrTy, "nLengths", NONE), CL.mkDecl(nrrdPtrTy, "nData", NONE)]
389 :     else [CL.mkDecl(nrrdPtrTy, "nData", NONE)]
390 : jhr 1736 val prDecls = outDecls @ [CL.mkDecl(filePtrTy, "outS", NONE)]
391 : jhr 1735 fun nrrdNew v = CL.mkAssign(v, CL.mkApply("nrrdNew", []))
392 :     fun nrrdNuke v = CL.mkCall("nrrdNuke", [v])
393 :     fun writeNrrd (ty, name) =
394 :     if isDyn ty
395 :     then [
396 :     nrrdNew (nLengthsV),
397 :     nrrdNew (nDataV),
398 :     CL.mkIfThenElse(
399 : jhr 1815 CL.mkApply(N.outputGet(tgt, name), [wrldV, nLengthsV, nDataV]),
400 : jhr 1735 (* then *)
401 : jhr 1872 error ("Error getting nrrd data: %s\n",
402 :     CL.mkApply("biffMsgStrGet", [CL.mkIndirect(wrldV, "errors")])),
403 : jhr 1735 (* else *)
404 :     CL.mkIfThen(
405 :     CL.mkBinOp(
406 :     CL.mkApply("nrrdSave", [
407 :     CL.mkStr(OS.Path.joinBaseExt{base=name^"-len", ext=SOME "nrrd"}),
408 :     nLengthsV, CL.mkVar "NULL"
409 :     ]),
410 :     CL.#||,
411 :     CL.mkApply("nrrdSave", [
412 :     CL.mkStr(OS.Path.joinBaseExt{base=name^"-data", ext=SOME "nrrd"}),
413 :     nDataV, CL.mkVar "NULL"
414 :     ])),
415 :     (* then *)
416 :     error ("Error saving nrrd: %s\n", CL.mkApply("biffGetDone", [NRRD]))
417 :     (* endif *))
418 :     (* endif *)),
419 :     nrrdNuke nLengthsV,
420 :     nrrdNuke nDataV
421 :     ]
422 :     else [
423 :     nrrdNew (nDataV),
424 :     CL.mkIfThenElse(
425 : jhr 1815 CL.mkApply(N.outputGet(tgt, name), [wrldV, nDataV]),
426 : jhr 1735 (* then *)
427 : jhr 1872 error ("Error getting nrrd data: %s\n",
428 :     CL.mkApply("biffMsgStrGet", [CL.mkIndirect(wrldV, "errors")])),
429 : jhr 1735 (* else *)
430 :     CL.mkIfThen(
431 :     CL.mkApply("nrrdSave", [
432 :     CL.mkStr(OS.Path.joinBaseExt{base=name, ext=SOME "nrrd"}),
433 :     nDataV, CL.mkVar "NULL"
434 :     ]),
435 :     (* then *)
436 :     error ("Error saving nrrd: %s\n", CL.mkApply("biffGetDone", [NRRD]))
437 :     (* endif *))
438 :     (* endif *)),
439 :     nrrdNuke nDataV
440 :     ]
441 : jhr 1736 fun printNrrd (ty, name) = [] (* FIXME *)
442 : jhr 1735 in [
443 :     CL.D_Func(["static"], CL.voidTy, "WriteOutput", [CL.PARAM([], wrldPtr tgt, "wrld")],
444 : jhr 1736 CL.mkBlock(outDecls @ List.foldr (fn (output, l) => writeNrrd output @ l) [] outputs)),
445 :     CL.D_Func(["static"], CL.voidTy, "PrintOutput", [CL.PARAM([], wrldPtr tgt, "wrld")],
446 :     CL.mkBlock(prDecls @ List.foldr (fn (output, l) => printNrrd output @ l) [] outputs))
447 : jhr 1735 ] end
448 :    
449 :     fun gen (tgt : TargetUtil.target_desc, nAxes) = let
450 : jhr 1912 fun getFn snapshot (ty, name) = let
451 :     val funcName = if snapshot
452 :     then N.snapshotGet(tgt, name)
453 :     else N.outputGet(tgt, name)
454 : jhr 1735 fun mkFunc (params, body) =
455 :     CL.D_Func([], CL.boolTy, funcName, CL.PARAM([], wrldPtr tgt, "wrld")::params, body)
456 :     in
457 :     case ty
458 : jhr 1912 of Ty.DynSeqTy ty' => mkFunc (genDynOutput(tgt, snapshot, nAxes, ty', name))
459 :     | _ => mkFunc (genFixedOutput(tgt, snapshot, nAxes, ty, name))
460 : jhr 1735 (* end case *)
461 :     end
462 :     fun gen' outputs = let
463 : jhr 1912 val getFns = List.map (getFn false) outputs
464 : jhr 1735 in
465 :     if (#exec tgt)
466 :     then getFns @ genOutput(tgt, outputs)
467 : jhr 1912 else if (#snapshot tgt)
468 :     then List.map (getFn true) outputs @ getFns
469 : jhr 1735 else getFns
470 :     end
471 : jhr 1707 in
472 : jhr 1735 gen'
473 : jhr 1707 end
474 :    
475 :     end

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