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

SCM Repository

[diderot] Diff of /branches/pure-cfg/src/compiler/cl-target/cl-target.sml
ViewVC logotype

Diff of /branches/pure-cfg/src/compiler/cl-target/cl-target.sml

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1321, Sun Jun 12 14:50:26 2011 UTC revision 1405, Wed Jun 29 18:52:17 2011 UTC
# Line 15  Line 15 
15      structure ToCL = TreeToCL      structure ToCL = TreeToCL
16      structure N = CNames      structure N = CNames
17    
18      (* translate TreeIL types to shadow types *)
19        fun shadowTy ty = (case ty
20               of Ty.BoolTy => CL.T_Named "cl_bool"
21                | Ty.StringTy => raise Fail "unexpected string type"
22                | Ty.IVecTy 1 => CL.T_Named(RN.shadowIntTy ())
23                | Ty.IVecTy n => raise Fail "unexpected int vector type"
24                | Ty.TensorTy[] => CL.T_Named(RN.shadowRealTy ())
25                | Ty.TensorTy[n] => CL.T_Named(RN.shadowVecTy n)
26                | Ty.TensorTy[n, m] => CL.T_Named(RN.shadowMatTy(n,m))
27                | Ty.ImageTy(ImageInfo.ImgInfo{dim, ...}) => CL.T_Named(RN.shadowImageTy dim)
28                | _ => raise Fail(concat["TreeToC.trType(", Ty.toString ty, ")"])
29              (* end case *))
30    
31      (* helper functions for specifying parameters in various address spaces *)
32        fun clParam (spc, ty, x) = CL.PARAM([spc], ty, x)
33        fun globalParam (ty, x) = CL.PARAM(["__global"], ty, x)
34        fun constantParam (ty, x) = CL.PARAM(["__constant"], ty, x)
35        fun localParam (ty, x) = CL.PARAM(["__local"], ty, x)
36        fun privateParam (ty, x) = CL.PARAM(["__private"], ty, x)
37    
38    (* C variable translation *)    (* C variable translation *)
39      structure TrCVar =      structure TrCVar =
40        struct        struct
# Line 57  Line 77 
77    (* variable or field that is mirrored between host and GPU *)    (* variable or field that is mirrored between host and GPU *)
78      type mirror_var = {      type mirror_var = {
79              hostTy : CL.ty,             (* variable type on Host (i.e., C type) *)              hostTy : CL.ty,             (* variable type on Host (i.e., C type) *)
80                shadowTy : CL.ty,           (* host-side shadow type of GPU type *)
81              gpuTy : CL.ty,              (* variable's type on GPU (i.e., OpenCL type) *)              gpuTy : CL.ty,              (* variable's type on GPU (i.e., OpenCL type) *)
82              var : CL.var                (* variable name *)              var : CL.var                (* variable name *)
83            }            }
# Line 79  Line 100 
100          topDecls : CL.decl list ref,          topDecls : CL.decl list ref,
101          strands : strand AtomTable.hash_table,          strands : strand AtomTable.hash_table,
102          initially :  CL.decl ref,          initially :  CL.decl ref,
103          numDims: int ref,          numDims: int ref,               (* number of dimensions in initially iteration *)
104          imgGlobals: (string * int) list ref,          imgGlobals: (string * int) list ref,
105          prFn: CL.decl ref          prFn: CL.decl ref
106        }        }
# Line 135  Line 156 
156                  case scope                  case scope
157  (* NOTE: if we move strand initialization to the GPU, then we'll have to change the following code! *)  (* NOTE: if we move strand initialization to the GPU, then we'll have to change the following code! *)
158                   of StrandScope stateVars =>                   of StrandScope stateVars =>
159                        ToC.trBlock (vMap, saveState "StrandScope" stateVars ToC.trAssign, blk)                        ToCL.trBlock (vMap, saveState "StrandScope" stateVars ToCL.trAssign, blk)
160                    | MethodScope stateVars =>                    | MethodScope stateVars =>
161                        ToCL.trBlock (vMap, saveState "MethodScope" stateVars ToCL.trAssign, blk)                        ToCL.trBlock (vMap, saveState "MethodScope" stateVars ToCL.trAssign, blk)
162                    | InitiallyScope => ToC.trBlock (vMap, fn (_, _, stm) => [stm], blk)                    | InitiallyScope => ToCL.trBlock (vMap, fn (_, _, stm) => [stm], blk)
163                    | _ => ToC.trBlock (vMap, fn (_, _, stm) => [stm], blk)                    | _ => ToC.trBlock (vMap, fn (_, _, stm) => [stm], blk)
164                  (* end case *)                  (* end case *)
165                end                end
# Line 148  Line 169 
169    (* variables *)    (* variables *)
170      structure Var =      structure Var =
171        struct        struct
172            fun mirror (ty, name) = {
173                    hostTy = ToC.trType ty,
174                    shadowTy = shadowTy ty,
175                    gpuTy = ToCL.trType ty,
176                    var = name
177                  }
178          fun name (ToCL.V(_, name)) = name          fun name (ToCL.V(_, name)) = name
179          fun global (Prog{globals, imgGlobals, ...}, name, ty) = let          fun global (Prog{globals, imgGlobals, ...}, name, ty) = let
180                val x = {hostTy = ToC.trType ty, gpuTy = ToCL.trType ty, var = name}                val x = mirror (ty, name)
181                fun isImgGlobal (Ty.ImageTy(ImageInfo.ImgInfo{dim, ...}), name) =                fun isImgGlobal (Ty.ImageTy(ImageInfo.ImgInfo{dim, ...}), name) =
182                      imgGlobals  := (name,dim) :: !imgGlobals                      imgGlobals  := (name,dim) :: !imgGlobals
183                  | isImgGlobal _ =  ()                  | isImgGlobal _ =  ()
# Line 162  Line 189 
189          fun param x = ToCL.V(ToCL.trType(V.ty x), V.name x)          fun param x = ToCL.V(ToCL.trType(V.ty x), V.name x)
190          fun state (Strand{state, ...}, x) = let          fun state (Strand{state, ...}, x) = let
191                val ty = V.ty x                val ty = V.ty x
192                val x' = {hostTy = ToC.trType ty, gpuTy = ToCL.trType ty, var = V.name x}                val x' = mirror (ty, V.name x)
193                in                in
194                  state := x' :: !state;                  state := x' :: !state;
195                  ToCL.V(#gpuTy x', #var x')                  ToCL.V(#gpuTy x', #var x')
# Line 205  Line 232 
232                    topDecls = ref [],                    topDecls = ref [],
233                    strands = AtomTable.mkTable (16, Fail "strand table"),                    strands = AtomTable.mkTable (16, Fail "strand table"),
234                    initially = ref(CL.D_Comment["missing initially"]),                    initially = ref(CL.D_Comment["missing initially"]),
235                    numDims = ref(0),                    numDims = ref 0,
236                    imgGlobals = ref[],                    imgGlobals = ref[],
237                    prFn = ref(CL.D_Comment(["No Print Function"]))                    prFn = ref(CL.D_Comment(["No Print Function"]))
238                  })                  })
239        (* register the global initialization part of a program *)  
 (* FIXME: unused code; can this be removed??  
           fun globalIndirects (globals,stms) = let  
                 fun getGlobals ({name,target as TargetUtil.TARGET_CL}::rest) =  
                       CL.mkAssign(CL.mkIndirect(CL.mkVar RN.globalsVarName,name),CL.mkVar name)  
                         ::getGlobals rest  
                   | getGlobals [] = []  
                   | getGlobals (_::rest) = getGlobals rest  
                 in  
                   stms @ getGlobals globals  
                 end  
 *)  
240        (* register the code that is used to register command-line options for input variables *)        (* register the code that is used to register command-line options for input variables *)
241          fun inputs (Prog{topDecls, ...}, stm) = let          fun inputs (Prog{topDecls, ...}, stm) = let
242                val inputsFn = CL.D_Func(                val inputsFn = CL.D_Func(
# Line 234  Line 250 
250        (* register the global initialization part of a program *)        (* register the global initialization part of a program *)
251          fun init (Prog{topDecls, ...}, init) = let          fun init (Prog{topDecls, ...}, init) = let
252                                    val globalsDecl = CL.mkAssign(CL.E_Var RN.globalsVarName,                                    val globalsDecl = CL.mkAssign(CL.E_Var RN.globalsVarName,
253                      CL.mkApply("malloc", [CL.mkApply("sizeof",[CL.mkVar RN.globalsTy])]))                      CL.mkApply("malloc", [CL.mkSizeof(CL.T_Named RN.globalsTy)]))
   
               val initGlobalsCall = CL.mkCall(RN.initGlobalsHelper,[])  
   
254                                          val initFn = CL.D_Func(                                          val initFn = CL.D_Func(
255                      [], CL.voidTy, RN.initGlobals, [],                      [], CL.voidTy, RN.initGlobals, [],
256                      CL.mkBlock([globalsDecl,initGlobalsCall]))                      CL.mkBlock[
257                val initFn_helper = CL.D_Func(              globalsDecl,
258                      [], CL.voidTy, RN.initGlobalsHelper, [],              CL.mkCall(RN.initGlobalsHelper, [CL.mkVar RN.globalsVarName])
259                  ])
260                  val initHelperFn = CL.D_Func(
261                        [], CL.voidTy, RN.initGlobalsHelper,
262                [CL.PARAM([], globPtrTy, RN.globalsVarName)],
263                      init)                      init)
264                val shutdownFn = CL.D_Func(                val shutdownFn = CL.D_Func(
265                      [], CL.voidTy, RN.shutdown,                      [], CL.voidTy, RN.shutdown,
266                      [CL.PARAM([], CL.T_Ptr(CL.T_Named RN.worldTy), "wrld")],                      [CL.PARAM([], CL.T_Ptr(CL.T_Named RN.worldTy), "wrld")],
267                      CL.S_Block[])                      CL.S_Block[])
268                in                in
269                  topDecls := shutdownFn :: initFn :: initFn_helper :: !topDecls                  topDecls := shutdownFn :: initFn :: initHelperFn :: !topDecls
270                end                end
271    
272           (* create and register the initially function for a program *)           (* create and register the initially function for a program *)
273          fun initially {          fun initially {
274                prog = Prog{name=progName, strands, initially, ...},                prog = Prog{name=progName, strands, initially, numDims, ...},
275                isArray : bool,                isArray : bool,
276                iterPrefix : stm list,                iterPrefix : stm list,
277                iters : (var * exp * exp) list,                iters : (var * exp * exp) list,
# Line 282  Line 300 
300                        CL.mkDecl(CL.T_Array(CL.int32, SOME nDims), "base", SOME(CL.I_Array baseInit)),                        CL.mkDecl(CL.T_Array(CL.int32, SOME nDims), "base", SOME(CL.I_Array baseInit)),
301                        CL.mkDecl(CL.T_Array(CL.uint32, SOME nDims), "size", SOME(CL.I_Array sizeInit)),                        CL.mkDecl(CL.T_Array(CL.uint32, SOME nDims), "size", SOME(CL.I_Array sizeInit)),
302                        CL.mkDecl(worldTy, wrld,                        CL.mkDecl(worldTy, wrld,
303                          SOME(CL.I_Exp(CL.E_Apply(N.allocInitially, [                          SOME(CL.I_Exp(CL.E_Apply(RN.allocInitially, [
304                              CL.mkVar "ProgramName",                              CL.mkVar "ProgramName",
305                              CL.mkUnOp(CL.%&, CL.E_Var(N.strandDesc name)),                              CL.mkUnOp(CL.%&, CL.E_Var(N.strandDesc name)),
306                              CL.E_Bool isArray,                              CL.E_Bool isArray,
# Line 323  Line 341 
341                      [CL.mkReturn(SOME(CL.E_Var "wrld"))])                      [CL.mkReturn(SOME(CL.E_Var "wrld"))])
342                val initFn = CL.D_Func([], worldTy, N.initially, [], body)                val initFn = CL.D_Func([], worldTy, N.initially, [], body)
343                in                in
344                    numDims := nDims;
345                  initially := initFn                  initially := initFn
346                end                end
347    
348        (***** OUTPUT *****)        (***** OUTPUT *****)
349          fun genStrandPrint (Strand{name, tyName, state, output, code,...}) = let          fun genStrandPrint (Strand{name, tyName, state, output, code,...}) = let
350              (* the print function *)              (* the print function *)
351                val prFnName = concat[name, "_print"]                val prFnName = concat[name, "Print"]
352                val prFn = let                val prFn = let
353                      val params = [                      val params = [
354                              CL.PARAM([], CL.T_Ptr(CL.T_Named "FILE"), "outS"),                              CL.PARAM([], CL.T_Ptr(CL.T_Named "FILE"), "outS"),
355                                CL.PARAM([], CL.T_Ptr(CL.T_Num(RawTypes.RT_UInt8)),"status"),
356                                CL.PARAM([], CL.intTy,"numStrands"),
357                              CL.PARAM([], CL.T_Ptr(CL.T_Named tyName), "self")                              CL.PARAM([], CL.T_Ptr(CL.T_Named tyName), "self")
358                            ]                            ]
359                      val SOME(ty, x) = !output                      val SOME(ty, x) = !output
360                      val outState = CL.mkIndirect(CL.mkVar "self", x)                      val outState = CL.mkSelect(CL.mkSubscript(CL.mkVar "self", CL.E_Var "i"), x)
361                      val prArgs = (case ty                      val prArgs = (case ty
362                             of Ty.IVecTy 1 => [CL.E_Str(!N.gIntFormat ^ "\n"), outState]                             of Ty.IVecTy 1 => [CL.E_Str(!N.gIntFormat ^ "\n"), outState]
363                              | Ty.IVecTy d => let                              | Ty.IVecTy d => let
# Line 358  Line 379 
379                                  end                                  end
380                              | _ => raise Fail("genStrand: unsupported output type " ^ Ty.toString ty)                              | _ => raise Fail("genStrand: unsupported output type " ^ Ty.toString ty)
381                            (* end case *))                            (* end case *))
382                        val forBody = CL.mkIfThen(
383                              CL.mkBinOp(CL.mkSubscript(CL.E_Var "status",CL.E_Var "i"), CL.#==, CL.E_Var "DIDEROT_STABILIZE"),
384                              CL.mkBlock([CL.mkCall("fprintf", CL.mkVar "outS" :: prArgs)]))
385                        val body =  CL.mkFor(
386                            [(CL.intTy, "i", CL.mkInt 0)],
387                            CL.mkBinOp(CL.E_Var "i", CL.#<, CL.E_Var "numStrands"),
388                            [CL.mkPostOp(CL.E_Var "i", CL.^++)],
389                            forBody)
390                      in                      in
391                        CL.D_Func(["static"], CL.voidTy, prFnName, params,                        CL.D_Func(["static"], CL.voidTy, prFnName, params, body)
                         CL.mkCall("fprintf", CL.mkVar "outS" :: prArgs))  
392                      end                      end
393                in                in
394                  prFn                  prFn
# Line 372  Line 400 
400                  List.rev (List.map (fn x => (targetTy x, #var x)) (!state)),                  List.rev (List.map (fn x => (targetTy x, #var x)) (!state)),
401                  tyName)                  tyName)
402    
       (* generates the load kernel function *)  
   
403        (* generates the opencl buffers for the image data *)        (* generates the opencl buffers for the image data *)
404          fun getGlobalDataBuffers (globals,contextVar,errVar) = let          fun getGlobalDataBuffers (globals, imgGlobals, contextVar, errVar) = let
405                  val globalBuffErr = "error creating OpenCL global buffer"
406                  fun errorFn msg = CL.mkIfThen(CL.mkBinOp(CL.E_Var errVar, CL.#!=, CL.E_Var "CL_SUCCESS"),
407                        CL.mkBlock([CL.mkCall("fprintf",[CL.E_Var "stderr", CL.E_Str msg]),
408                        CL.mkCall("exit",[CL.mkInt 1])]))
409                  val shadowTypeDecl =
410                        CL.mkDecl(CL.T_Named(RN.shadowGlobalsTy), RN.shadowGlaobalsName, NONE)
411                  val globalImagesToShadowStms = List.map (fn (var,nDims) =>
412                        CL.mkCall((RN.shadowImageFunc nDims), [
413                             CL.mkVar contextVar,
414                             CL.mkUnOp(CL.%&,CL.mkSelect(CL.mkVar(RN.shadowGlaobalsName),var)),
415    (* FIXME: for vectors and matrices, we need to invoke the appropriate shadow function from shadow-types.h *)
416                             CL.mkIndirect(CL.mkVar(RN.globalsVarName),var)
417                             ])) imgGlobals
418                (* Converts only the non-image-field types into their corresponding global shadow types *)
419                  fun convertToShadow ((global:mirror_var)::rest,(imgGlobal,nDim)::restImages) =
420                        if (#var global) = imgGlobal
421                          then convertToShadow(rest,restImages)
422                          else CL.mkAssign(CL.mkSelect(CL.mkVar RN.shadowGlaobalsName, #var global),
423                              CL.mkIndirect(CL.mkVar(RN.globalsVarName), #var global)) ::
424                            convertToShadow(rest,(imgGlobal,nDim)::restImages)
425                    | convertToShadow ([], _) = []
426                    | convertToShadow ((global:mirror_var)::rest, []) =
427                        CL.mkAssign(CL.mkSelect(CL.mkVar(RN.shadowGlaobalsName),#var global),
428                            CL.mkIndirect(CL.mkVar(RN.globalsVarName), #var global)) ::
429                        convertToShadow(rest,[])
430                  val globalToShadowStms = convertToShadow(globals,imgGlobals)
431                val globalBufferDecl =  CL.mkDecl(clMemoryTy,concat[RN.globalsVarName,"_cl"],NONE)                val globalBufferDecl =  CL.mkDecl(clMemoryTy,concat[RN.globalsVarName,"_cl"],NONE)
432                val globalBuffer = CL.mkAssign(CL.mkVar(concat[RN.globalsVarName,"_cl"]),                val globalBuffer = CL.mkAssign(CL.mkVar(concat[RN.globalsVarName,"_cl"]),
433                      CL.mkApply("clCreateBuffer", [                      CL.mkApply("clCreateBuffer", [
434                          CL.mkVar contextVar,                          CL.mkVar contextVar,
435                          CL.mkVar "CL_MEM_COPY_HOST_PTR",                          CL.mkVar "CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR",
436                          CL.mkApply("sizeof",[CL.mkVar RN.globalsTy]),                          CL.mkSizeof(CL.T_Named RN.shadowGlobalsTy),
437                          CL.mkVar RN.globalsVarName,                          CL.mkUnOp(CL.%&,CL.mkVar RN.shadowGlaobalsName),
438                          CL.mkUnOp(CL.%&,CL.mkVar errVar)                          CL.mkUnOp(CL.%&,CL.mkVar errVar)
439                        ]))                        ]))
440                fun genDataBuffers ([],_,_) = []                fun genDataBuffers ([],_,_,_) = []
441                  | genDataBuffers ((var,nDims)::globals, contextVar, errVar) = let                  | genDataBuffers ((var,nDims)::globals, contextVar, errVar,errFn) = let
442                      val hostVar = CL.mkIndirect(CL.mkVar RN.globalsVarName, var)                      val hostVar = CL.mkIndirect(CL.mkVar RN.globalsVarName, var)
443  (* FIXME: use CL constructors to build expressions (not strings) *)                      val size = CL.mkIndirect(hostVar, "dataSzb")
                     fun sizeExp i = CL.mkSubscript(CL.mkIndirect(hostVar, "size"), CL.mkInt i)  
                     val size = CL.mkBinOp(CL.mkApply("sizeof",[CL.mkVar "float"]), CL.#*, sizeExp 0)  
                     val size = if (nDims > 1)  
                           then CL.mkBinOp(size, CL.#*, sizeExp 1)  
                           else size  
                     val size = if (nDims > 2)  
                           then CL.mkBinOp(size, CL.#*, sizeExp 2)  
                           else size  
444                      in                      in
                       CL.mkDecl(clMemoryTy, RN.addBufferSuffix var ,NONE)::  
445                        CL.mkDecl(clMemoryTy, RN.addBufferSuffixData var ,NONE)::                        CL.mkDecl(clMemoryTy, RN.addBufferSuffixData var ,NONE)::
                       CL.mkAssign(CL.mkVar(RN.addBufferSuffix var),  
                         CL.mkApply("clCreateBuffer", [  
                             CL.mkVar contextVar,  
                             CL.mkVar "CL_MEM_COPY_HOST_PTR",  
                             CL.mkApply("sizeof",[CL.mkVar (RN.imageTy nDims)]),  
                             hostVar,  
                             CL.mkUnOp(CL.%&,CL.mkVar errVar)  
                           ])) ::  
446                        CL.mkAssign(CL.mkVar(RN.addBufferSuffixData var),                        CL.mkAssign(CL.mkVar(RN.addBufferSuffixData var),
447                          CL.mkApply("clCreateBuffer", [                          CL.mkApply("clCreateBuffer", [
448                              CL.mkVar contextVar,                              CL.mkVar contextVar,
449                              CL.mkVar "CL_MEM_COPY_HOST_PTR",                              CL.mkVar "CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR",
450                              size,                              size,
451                              CL.mkIndirect(hostVar, "data"),                              CL.mkIndirect(hostVar, "data"),
452                              CL.mkUnOp(CL.%&,CL.mkVar errVar)                              CL.mkUnOp(CL.%&,CL.mkVar errVar)
453                            ])) :: genDataBuffers(globals,contextVar,errVar)                            ])) ::
454                            errFn(concat["error in creating ",RN.addBufferSuffixData var, " global buffer"]) ::
455                            genDataBuffers(globals,contextVar,errVar,errFn)
456                      end                      end
457                in                in
458                  globalBufferDecl :: globalBuffer :: genDataBuffers(globals,contextVar,errVar)                  [shadowTypeDecl] @ globalImagesToShadowStms @ globalToShadowStms
459                    @ [globalBufferDecl, globalBuffer,errorFn(globalBuffErr)]
460                    @ genDataBuffers(imgGlobals,contextVar,errVar,errorFn)
461                end                end
462    
463        (* generates the kernel arguments for the image data *)        (* generates the kernel arguments for the image data *)
464          fun genGlobalArguments (globals, count, kernelVar, errVar) = let          fun genGlobalArguments (globals, count, kernelVar, errVar) = let
465                val globalArgument = CL.mkExpStm(CL.mkAssignOp(CL.mkVar errVar,CL.|=,                val globalArgErr = "error creating OpenCL global argument"
466                  fun errorFn msg = CL.mkIfThen(CL.mkBinOp(CL.E_Var errVar, CL.#!=, CL.E_Var "CL_SUCCESS"),
467                        CL.mkBlock([CL.mkCall("fprintf",[CL.E_Var "stderr", CL.E_Str msg]),
468                        CL.mkCall("exit",[CL.mkInt 1])]))
469                  val globalArgument = CL.mkExpStm(CL.mkAssignOp(CL.mkVar errVar,CL.&=,
470                      CL.mkApply("clSetKernelArg",                      CL.mkApply("clSetKernelArg",
471                        [CL.mkVar kernelVar,                        [CL.mkVar kernelVar,
472                         CL.mkPostOp(CL.E_Var count, CL.^++),                         CL.mkPostOp(CL.E_Var count, CL.^++),
473                         CL.mkApply("sizeof",[CL.mkVar "cl_mem"]),                         CL.mkApply("sizeof",[CL.mkVar "cl_mem"]),
474                         CL.mkUnOp(CL.%&,CL.mkVar(concat[RN.globalsVarName,"_cl"]))])))                         CL.mkUnOp(CL.%&,CL.mkVar(concat[RN.globalsVarName,"_cl"]))])))
475                fun genDataArguments ([],_,_,_) = []                fun genDataArguments ([],_,_,_,_) = []
476                  | genDataArguments ((var,nDims)::globals,count,kernelVar,errVar) =                  | genDataArguments ((var,nDims)::globals,count,kernelVar,errVar,errFn) =
477                      CL.mkExpStm(CL.mkAssignOp(CL.mkVar errVar,CL.|=,                      CL.mkExpStm(CL.mkAssignOp(CL.mkVar errVar,CL.$=,
                       CL.mkApply("clSetKernelArg",  
                         [CL.mkVar kernelVar,  
                          CL.mkPostOp(CL.E_Var count, CL.^++),  
                          CL.mkApply("sizeof",[CL.mkVar "cl_mem"]),  
                          CL.mkUnOp(CL.%&,CL.mkVar(RN.addBufferSuffix var))]))) ::  
                     CL.mkExpStm(CL.mkAssignOp(CL.mkVar errVar,CL.|=,  
478                        CL.mkApply("clSetKernelArg",                        CL.mkApply("clSetKernelArg",
479                          [CL.mkVar kernelVar,                          [CL.mkVar kernelVar,
480                           CL.mkPostOp(CL.E_Var count, CL.^++),                           CL.mkPostOp(CL.E_Var count, CL.^++),
481                           CL.mkApply("sizeof",[CL.mkVar "cl_mem"]),                           CL.mkApply("sizeof",[CL.mkVar "cl_mem"]),
482                           CL.mkUnOp(CL.%&,CL.mkVar(RN.addBufferSuffixData var))]))) ::                           CL.mkUnOp(CL.%&,CL.mkVar(RN.addBufferSuffixData var))]))) ::
483                      genDataArguments (globals,count,kernelVar,errVar)                           errFn(concat["error in creating ",RN.addBufferSuffixData var, " argument"]) ::
484                        genDataArguments (globals,count,kernelVar,errVar,errFn)
485                in                in
486                  globalArgument :: genDataArguments(globals, count, kernelVar, errVar)                 [globalArgument,errorFn(globalArgErr)] @ genDataArguments(globals, count, kernelVar, errVar,errorFn)
487                end                end
488    
489        (* generates the globals buffers and arguments function *)        (* generates the globals buffers and arguments function *)
490          fun genGlobalBuffersArgs (imgGlobals) = let          fun genGlobalBuffersArgs (globals,imgGlobals) = let
491              (* Delcare opencl setup objects *)              (* Delcare opencl setup objects *)
492                val errVar = "err"                val errVar = "err"
493                val imgDataSizeVar = "image_dataSize"                val imgDataSizeVar = "image_dataSize"
494                val params = [                val params = [
495                        CL.PARAM([],CL.T_Named("cl_context"), "context"),                        CL.PARAM([],CL.T_Named("cl_context"), "context"),
496                        CL.PARAM([],CL.T_Named("cl_kernel"), "kernel"),                        CL.PARAM([],CL.T_Named("cl_kernel"), "kernel"),
497                          CL.PARAM([],CL.T_Named("cl_command_queue"), "cmdQ"),
498                        CL.PARAM([],CL.T_Named("int"), "argStart")                        CL.PARAM([],CL.T_Named("int"), "argStart")
499                      ]                      ]
500                val clGlobalBuffers = getGlobalDataBuffers(!imgGlobals, "context", errVar)                val clGlobalBuffers = getGlobalDataBuffers(globals,!imgGlobals, "context", errVar)
501                val clGlobalArguments = genGlobalArguments(!imgGlobals, "argStart", "kernel", errVar)                val clGlobalArguments = genGlobalArguments(!imgGlobals, "argStart", "kernel", errVar)
502              (* Body put all the statments together *)              (* Body put all the statments together *)
503                val body = CL.mkDecl(clIntTy, errVar, SOME(CL.I_Exp(CL.mkInt 0)))                val body = CL.mkDecl(clIntTy, errVar, SOME(CL.I_Exp(CL.mkInt 0)))
# Line 469  Line 508 
508    
509        (* generate the data and global parameters *)        (* generate the data and global parameters *)
510          fun genKeneralGlobalParams ((name,tyname)::rest) =          fun genKeneralGlobalParams ((name,tyname)::rest) =
511                CL.PARAM([], CL.T_Ptr(CL.T_Named RN.globalsTy), concat[RN.globalsVarName]) ::                globalParam (CL.T_Ptr(CL.voidTy), RN.addBufferSuffixData name) ::
               CL.PARAM([], CL.T_Ptr(CL.T_Named (RN.imageTy tyname)),RN.addBufferSuffix name) ::  
               CL.PARAM([], CL.T_Ptr(CL.voidTy),RN.addBufferSuffixData name) ::  
512                genKeneralGlobalParams rest                genKeneralGlobalParams rest
513            | genKeneralGlobalParams [] = []            | genKeneralGlobalParams [] = []
514    
       (*generate code for intilizing kernel global data *)  
 (* FIXME: should use List.map here *)  
         fun initGlobalImages ((name, tyname)::rest) =  
              CL.mkAssign(CL.mkIndirect(CL.E_Var RN.globalsVarName, name), CL.mkVar (RN.addBufferSuffix name)) ::  
              CL.mkAssign(CL.mkIndirect(CL.E_Var RN.globalsVarName,concat[name,"->","data"]),CL.mkVar (RN.addBufferSuffixData name)) ::  
              initGlobalImages rest  
           | initGlobalImages [] = []  
   
515          (* generate the main kernel function for the .cl file *)          (* generate the main kernel function for the .cl file *)
516          fun genKernelFun (strand, nDims, globals, imgGlobals) = let          fun genKernelFun (strand, nDims, globals, imgGlobals) = let
517                val Strand{name, tyName, state, output, code,...} = strand                val Strand{name, tyName, state, output, code,...} = strand
518                val fName = RN.kernelFuncName;                val fName = RN.kernelFuncName;
519                val inState = "strand_in"                val inState = "strand_in"
520                val outState = "strand_out"                val outState = "strand_out"
521                  val tempVar = "tmp"
522                val params = [                val params = [
523                        CL.PARAM(["__global"], CL.T_Ptr(CL.T_Named tyName), "selfIn"),                        CL.PARAM(["__global"], CL.T_Ptr(CL.T_Named tyName), "selfIn"),
524                        CL.PARAM(["__global"], CL.T_Ptr(CL.T_Named tyName), "selfOut"),                        CL.PARAM(["__global"], CL.T_Ptr(CL.T_Named tyName), "selfOut"),
525                        CL.PARAM(["__global"], CL.intTy, "width")                        CL.PARAM(["__global"], CL.T_Ptr(CL.T_Num(RawTypes.RT_UInt8)), "strandStatus"),
526                          CL.PARAM(["__global"], CL.intTy, "width"),
527                          CL.PARAM(["__global"], globPtrTy, RN.globalsVarName)
528                      ] @ genKeneralGlobalParams(!imgGlobals)                      ] @ genKeneralGlobalParams(!imgGlobals)
529                val thread_ids = if nDims = 1                val thread_ids = if nDims = 1
530                      then [                      then [
531                          CL.mkDecl(CL.intTy, "x", SOME(CL.I_Exp(CL.mkInt 0))),                            CL.mkDecl(CL.intTy, "x",
532                          CL.mkAssign(CL.mkVar "x",CL.mkApply(RN.getGlobalThreadId,[CL.mkInt 0]))                              SOME(CL.I_Exp(CL.mkApply(RN.getGlobalThreadId,[CL.mkInt 0]))))
533                        ]                        ]
534                      else [                      else if nDims = 2
535                          CL.mkDecl(CL.intTy, "x", SOME(CL.I_Exp(CL.mkInt 0))),                        then [
536                          CL.mkDecl(CL.intTy, "y", SOME(CL.I_Exp(CL.mkInt 0))),                            CL.mkDecl(CL.intTy, "x",
537                          CL.mkAssign(CL.mkVar "x",  CL.mkApply(RN.getGlobalThreadId,[CL.mkInt 0])),                              SOME(CL.I_Exp(CL.mkApply(RN.getGlobalThreadId,[CL.mkInt 0])))),
538                          CL.mkAssign(CL.mkVar "y",CL.mkApply(RN.getGlobalThreadId,[CL.mkInt 1]))                            CL.mkDecl(CL.intTy, "y",
539                                SOME(CL.I_Exp(CL.mkApply(RN.getGlobalThreadId,[CL.mkInt 1]))))
540                        ]                        ]
541                        else raise Fail "nDims > 2"
542                val strandDecl = [                val strandDecl = [
543                      CL.mkDecl(CL.T_Named tyName, inState, NONE),                        CL.mkDecl(CL.T_Ptr(CL.T_Named (concat["__global ",tyName])), inState, NONE),
544                      CL.mkDecl(CL.T_Named tyName, outState,NONE)]                        CL.mkDecl(CL.T_Ptr(CL.T_Named (concat["__global ",tyName])), outState, NONE),
545                val strandObjects = if nDims = 1                        CL.mkDecl(CL.T_Ptr(CL.T_Named (concat["__global ",tyName])), tempVar, NONE)
                     then [  
                         CL.mkAssign( CL.mkVar inState, CL.mkSubscript(CL.mkVar "selfIn", CL.mkStr "x")),  
                         CL.mkAssign(CL.mkVar outState,CL.mkSubscript(CL.mkVar "selfOut", CL.mkStr "x"))  
546                        ]                        ]
547                      else let                val imageDataDecl = CL.mkDecl(CL.T_Named(RN.imageDataType),RN.globalImageDataName,NONE)
548                        val index = CL.mkBinOp(CL.mkBinOp(CL.mkVar "x",CL.#*,CL.mkVar "width"),CL.#+,CL.mkVar "y")                val imageDataStms = List.map (fn (x,_) =>
549                        in [                    CL.mkAssign(CL.mkSelect(CL.mkVar(RN.globalImageDataName),RN.imageDataName x),
550                          CL.mkAssign(CL.mkVar inState, CL.mkSubscript(CL.mkVar "selfIn",index)),                                CL.mkVar(RN.addBufferSuffixData x))) (!imgGlobals)
551                          CL.mkAssign(CL.mkVar outState,CL.mkSubscript(CL.mkVar "selfOut",index))                val barrierCode = CL.mkIfThen(CL.mkBinOp(CL.E_Var "status",CL.#==,CL.E_Var "DIDEROT_ACTIVE"),
552                        ] end                                   CL.mkBlock ([CL.mkAssign(CL.E_Var tempVar, CL.E_Var inState),
553                val status = CL.mkDecl(CL.intTy, "status", SOME(CL.I_Exp(CL.mkInt 0)))                                   CL.mkAssign(CL.E_Var inState, CL.E_Var outState),
554                val strand_Init_Stm = CL.mkCall(RN.strandInit name, [CL.E_Var RN.globalsVarName,CL.mkUnOp(CL.%&,CL.E_Var inState), CL.E_Var "x", CL.E_Var "y"])                                   CL.mkAssign(CL.E_Var outState, CL.E_Var tempVar)]))
555                val local_vars = thread_ids @ initGlobalImages(!imgGlobals)  @ strandDecl @ strandObjects @ [strand_Init_Stm,status]                val barrierStm = CL.mkCall("barrier",[CL.E_Var "CLK_LOCAL_MEM_FENCE"])
556                                    val while_exp = CL.mkBinOp(                val index = if nDims = 1 then
557                      CL.mkBinOp(CL.mkVar "status",CL.#!=, CL.mkVar RN.kStabilize),                          CL.mkStr "x"
558                      CL.#||,                      else
559                      CL.mkBinOp(CL.mkVar "status", CL.#!=, CL.mkVar RN.kDie))                          CL.mkBinOp(
560                val whileBody = CL.mkBlock [                              CL.mkBinOp(CL.mkVar "x", CL.#*, CL.mkVar "width"), CL.#+, CL.mkVar "y")
561    
562                  val strandObjects =
563                         [ CL.mkAssign(CL.mkVar inState,  CL.mkBinOp(CL.mkVar "selfIn",CL.#+,index)),
564                           CL.mkAssign(CL.mkVar outState, CL.mkBinOp(CL.mkVar "selfOut",CL.#+,index))
565                         ]
566    
567                    val stabalizeStm = CL.mkAssign(CL.mkSubscript(CL.mkVar "strandStatus",index),
568                                                                            CL.E_Var "status")
569                  val status = CL.mkDecl(CL.intTy, "status", SOME(CL.I_Exp(CL.mkSubscript(CL.mkVar "strandStatus",index))))
570                  val strandInitStm = CL.mkCall(RN.strandInit name, [
571                          CL.mkVar RN.globalsVarName,
572                          CL.mkVar inState,
573                          CL.mkVar "x",
574    (* FIXME: if nDims = 1, then "y" is not defined! the arguments to this call should really come from
575     * the initially code!
576     *)
577                          CL.mkVar "y"])
578                  val local_vars = thread_ids
579                        @ [imageDataDecl]
580                        @ imageDataStms
581                        @ strandDecl
582                        @ strandObjects
583                        @ [strandInitStm,status]
584                  val while_exp = CL.mkBinOp(CL.mkVar "status",CL.#==, CL.mkVar RN.kActive)
585                  val whileBody = CL.mkBlock ([
586                        CL.mkAssign(CL.mkVar "status",                        CL.mkAssign(CL.mkVar "status",
587                          CL.mkApply(RN.strandUpdate name,                          CL.mkApply(RN.strandUpdate name,
588                            [CL.mkUnOp(CL.%&,CL.mkVar inState), CL.mkUnOp(CL.%&,CL.mkVar outState),CL.E_Var RN.globalsVarName])),                            [CL.mkVar inState,
589                        CL.mkCall(RN.strandStabilize name,                             CL.mkVar outState,
590                          [CL.mkUnOp(CL.%&,CL.mkVar inState), CL.mkUnOp(CL.%&,CL.mkVar outState),CL.E_Var RN.globalsVarName])                             CL.mkVar RN.globalsVarName,
591                      ]                             CL.mkVar RN.globalImageDataName]))] @ [barrierCode,barrierStm] )
592                val whileBlock = [CL.mkWhile(while_exp, whileBody)]                val whileBlock = [CL.mkWhile(while_exp, whileBody)]
593                val body = CL.mkBlock(local_vars  @ whileBlock)                val body = CL.mkBlock(local_vars @ whileBlock @ [stabalizeStm])
594                in                in
595                  CL.D_Func(["__kernel"], CL.voidTy, fName, params, body)                  CL.D_Func(["__kernel"], CL.voidTy, fName, params, body)
596                end                end
597        (* generate a global structure from the globals *)  
598          fun genGlobalStruct (targetTy, globals) = let        (* generate a global structure type definition from the list of globals *)
599            fun genGlobalStruct (targetTy, globals, tyName) = let
600                val globs = List.map (fn (x : mirror_var) => (targetTy x, #var x)) globals                val globs = List.map (fn (x : mirror_var) => (targetTy x, #var x)) globals
601                in                in
602                  CL.D_StructDef(globs, RN.globalsTy)                  CL.D_StructDef(globs, tyName)
603                end                end
604    
605          (* generate a global structure type definition from the image data of the image globals *)
606            fun genImageDataStruct (imgGlobals, tyName) = let
607                  val globs = List.map (fn (x,_) => (CL.T_Ptr(CL.imageDataTy "__global"),(RN.imageDataName x))) imgGlobals
608                  in
609                    CL.D_StructDef(globs, tyName)
610                  end
611    
612          fun genGlobals (declFn, targetTy, globals) = let          fun genGlobals (declFn, targetTy, globals) = let
613                fun doVar (x : mirror_var) = declFn (CL.D_Var([], targetTy x, #var x, NONE))                fun doVar (x : mirror_var) = declFn (CL.D_Var([], targetTy x, #var x, NONE))
614                in                in
# Line 563  Line 628 
628                            ("outputSzb", CL.I_Exp(CL.mkSizeof(ToC.trTy outTy))),                            ("outputSzb", CL.I_Exp(CL.mkSizeof(ToC.trTy outTy))),
629  *)  *)
630                            ("update", fnPtr("update_method_t", "0")),                            ("update", fnPtr("update_method_t", "0")),
631                            ("print", fnPtr("print_method_t", name ^ "_print"))                            ("print", fnPtr("print_method_t", name ^ "Print"))
632                          ]                          ]
633                      end                      end
634                val desc = CL.D_Var([], CL.T_Named N.strandDescTy, N.strandDesc name, SOME descI)                val desc = CL.D_Var([], CL.T_Named N.strandDescTy, N.strandDesc name, SOME descI)
# Line 608  Line 673 
673                      "#define DIDEROT_TARGET_CL",                      "#define DIDEROT_TARGET_CL",
674                      "#include \"Diderot/cl-diderot.h\""                      "#include \"Diderot/cl-diderot.h\""
675                    ]));                    ]));
676                  clppDecl (genGlobalStruct (#gpuTy, !globals));                  clppDecl (genGlobalStruct (#gpuTy, !globals, RN.globalsTy));
677                    clppDecl (genImageDataStruct(!imgGlobals,RN.imageDataType));
678                  clppDecl (genStrandTyDef(#gpuTy, strand));                  clppDecl (genStrandTyDef(#gpuTy, strand));
679                  clppDecl  (!init_code);                  clppDecl  (!init_code);
680                  List.app clppDecl (!code);                  List.app clppDecl (!code);
# Line 623  Line 689 
689                    ]));                    ]));
690                  cppDecl (CL.D_Var(["static"], CL.charPtr, "ProgramName",                  cppDecl (CL.D_Var(["static"], CL.charPtr, "ProgramName",
691                    SOME(CL.I_Exp(CL.mkStr progName))));                    SOME(CL.I_Exp(CL.mkStr progName))));
692                  cppDecl (genGlobalStruct (#hostTy, !globals));                  cppDecl (genGlobalStruct (#hostTy, !globals, RN.globalsTy));
693                  cppDecl (CL.D_Var(["static"], CL.T_Ptr(CL.T_Named RN.globalsTy), RN.globalsVarName, NONE));                  cppDecl (genGlobalStruct (#shadowTy, !globals, RN.shadowGlobalsTy));
694    (* FIXME: does this really need to be a global? *)
695                    cppDecl (CL.D_Var(["static"], globPtrTy, RN.globalsVarName, NONE));
696                  cppDecl (genStrandTyDef (#hostTy, strand));                  cppDecl (genStrandTyDef (#hostTy, strand));
697                  cppDecl (genStrandPrint strand);                  cppDecl (genStrandPrint strand);
698                  List.app cppDecl (List.rev (!topDecls));                  List.app cppDecl (List.rev (!topDecls));
699                  cppDecl (genGlobalBuffersArgs imgGlobals);                  cppDecl (genGlobalBuffersArgs (!globals,imgGlobals));
700                  List.app (fn strand => cppDecl (genStrandDesc strand)) strands;                  List.app (fn strand => cppDecl (genStrandDesc strand)) strands;
701                  genStrandTable (cppDecl, strands);                  genStrandTable (cppDecl, strands);
702                  cppDecl (!initially);                  cppDecl (!initially);
# Line 638  Line 706 
706                  TextIO.closeOut clOutS                  TextIO.closeOut clOutS
707                end                end
708    
709        (* output the code to a file.  The string is the basename of the file, the extension        (* output the code to the filesystem.  The string is the basename of the source file *)
        * is provided by the target.  
        *)  
710          fun generate (basename, prog as Prog{double, parallel, debug, ...}) = let          fun generate (basename, prog as Prog{double, parallel, debug, ...}) = let
711                fun condCons (true, x, xs) = x::xs                fun condCons (true, x, xs) = x::xs
712                  | condCons (false, _, xs) = xs                  | condCons (false, _, xs) = xs
# Line 695  Line 761 
761          fun init (Strand{name, tyName, code, init_code, ...}, params, init) = let          fun init (Strand{name, tyName, code, init_code, ...}, params, init) = let
762                val fName = RN.strandInit name                val fName = RN.strandInit name
763                val params =                val params =
764                      CL.PARAM([], globPtrTy, RN.globalsVarName) ::                      globalParam (globPtrTy, RN.globalsVarName) ::
765                      CL.PARAM([], CL.T_Ptr(CL.T_Named tyName), "selfOut") ::                      globalParam (CL.T_Ptr(CL.T_Named tyName), "selfOut") ::
766                        List.map (fn (ToCL.V(ty, x)) => CL.PARAM([], ty, x)) params                        List.map (fn (ToCL.V(ty, x)) => CL.PARAM([], ty, x)) params
767                val initFn = CL.D_Func([], CL.voidTy, fName, params, init)                val initFn = CL.D_Func([], CL.voidTy, fName, params, init)
768                in                in
# Line 707  Line 773 
773          fun method (Strand{name, tyName, code,...}, methName, body) = let          fun method (Strand{name, tyName, code,...}, methName, body) = let
774                val fName = concat[name, "_", methName]                val fName = concat[name, "_", methName]
775                val params = [                val params = [
776                        CL.PARAM([], CL.T_Ptr(CL.T_Named tyName), "selfIn"),                        globalParam (CL.T_Ptr(CL.T_Named tyName), "selfIn"),
777                        CL.PARAM([], CL.T_Ptr(CL.T_Named tyName), "selfOut"),                        globalParam (CL.T_Ptr(CL.T_Named tyName), "selfOut"),
778                                                           CL.PARAM([], CL.T_Ptr(CL.T_Named (RN.globalsTy)), RN.globalsVarName)                        globalParam (CL.T_Ptr(CL.T_Named (RN.globalsTy)), RN.globalsVarName),
779                          CL.PARAM([],CL.T_Named(RN.imageDataType),RN.globalImageDataName)
780                      ]                      ]
781                val methFn = CL.D_Func([], CL.int32, fName, params, body)                val methFn = CL.D_Func([], CL.int32, fName, params, body)
782                in                in

Legend:
Removed from v.1321  
changed lines
  Added in v.1405

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