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

SCM Repository

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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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