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 1306, Sat Jun 11 01:39:54 2011 UTC revision 1307, Sat Jun 11 13:58:02 2011 UTC
# Line 72  Line 72 
72      val clPlatformIdTy = CL.T_Named "cl_platform_id"      val clPlatformIdTy = CL.T_Named "cl_platform_id"
73      val clMemoryTy = CL.T_Named "cl_mem"      val clMemoryTy = CL.T_Named "cl_mem"
74    
75      (* variable or field that is mirrored between host and GPU *)
76        type mirror_var = {
77                hostTy : CL.ty,             (* variable type on Host (i.e., C type) *)
78                gpuTy : CL.ty,              (* variable's type on GPU (i.e., OpenCL type) *)
79                var : CL.var                (* variable name *)
80              }
81    
82      datatype strand = Strand of {      datatype strand = Strand of {
83          name : string,          name : string,
84          tyName : string,          tyName : string,
85          state : var list ref,          state : mirror_var list ref,
86          output : (Ty.ty * CL.var) option ref,   (* the strand's output variable (only one for now) *)          output : (Ty.ty * CL.var) option ref,   (* the strand's output variable (only one for now) *)
87          code : CL.decl list ref,          code : CL.decl list ref,
88          init_code: CL.decl ref          init_code: CL.decl ref
# Line 86  Line 93 
93          double : bool,                  (* true for double-precision support *)          double : bool,                  (* true for double-precision support *)
94          parallel : bool,                (* true for multithreaded (or multi-GPU) target *)          parallel : bool,                (* true for multithreaded (or multi-GPU) target *)
95          debug : bool,                   (* true for debug support in executable *)          debug : bool,                   (* true for debug support in executable *)
96          globals : {target:TargetUtil.target, globalTy:CL.ty, name:CLang.var} list ref,          globals : mirror_var list ref,
97          topDecls : CL.decl list ref,          topDecls : CL.decl list ref,
98          strands : strand AtomTable.hash_table,          strands : strand AtomTable.hash_table,
99          initially :  CL.decl ref,          initially :  CL.decl ref,
# Line 150  Line 157 
157      structure Var =      structure Var =
158        struct        struct
159          fun name (ToCL.V(_, name)) = name          fun name (ToCL.V(_, name)) = name
160          fun global (Prog{globals, imgGlobals, ...}, global_name, ty) = let          fun global (Prog{globals, imgGlobals, ...}, name, ty) = let
161                val cl_ty  = ToCL.trType ty                val x = {hostTy = ToC.trType ty, gpuTy = ToCL.trType ty, var = name}
162                                    val c_ty = ToC.trType ty                fun isImgGlobal (Ty.ImageTy(ImageInfo.ImgInfo{dim, ...}), name) =
163                fun isImgGlobal (imgGlobals, Ty.ImageTy(ImageInfo.ImgInfo{dim, ...}), name) =  imgGlobals  := (name,dim):: !imgGlobals                      imgGlobals  := (name,dim) :: !imgGlobals
164                  | isImgGlobal (imgGlobals, _, _) =  ()                  | isImgGlobal _ =  ()
165                in                in
166                  globals := {target =TargetUtil.TARGET_CL,globalTy = cl_ty, name = global_name} :: !globals;                  globals := x :: !globals;
167                                           globals := {target =TargetUtil.TARGET_C, globalTy = c_ty, name = global_name} :: !globals;                  isImgGlobal (ty, name);
168                  isImgGlobal(imgGlobals,ty,global_name);                  ToCL.V(#gpuTy x, name)
                 ToCL.V(cl_ty, global_name)  
169                end                end
170          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)
171          fun state (Strand{state, ...}, x) = let          fun state (Strand{state, ...}, x) = let
172                val ty' = ToCL.trType(V.ty x)                val ty = V.ty x
173                val x' = ToCL.V(ty', V.name x)                val x' = {hostTy = ToC.trType ty, gpuTy = ToCL.trType ty, var = V.name x}
174                in                in
175                  state := x' :: !state;                  state := x' :: !state;
176                  x'                  ToCL.V(#gpuTy x', #var x')
177                end                end
178        end        end
179    
# Line 360  Line 366 
366                                   prFn                                   prFn
367                end                end
368    
369          fun genStrandTyDef (Strand{tyName, state,...}) =          fun genStrandTyDef (targetTy, Strand{tyName, state,...}) =
370              (* the type declaration for the strand's state struct *)              (* the type declaration for the strand's state struct *)
371                CL.D_StructDef(                CL.D_StructDef(
372                        List.rev (List.map (fn CL.V(ty, x) => (ty, x)) (!state)),                  List.rev (List.map (fn x => (targetTy x, #var x)) (!state)),
373                        tyName)                        tyName)
374    
375    
# Line 372  Line 378 
378  (* generates the opencl buffers for the image data *)  (* generates the opencl buffers for the image data *)
379          fun getGlobalDataBuffers(globals,contextVar,errVar) = let          fun getGlobalDataBuffers(globals,contextVar,errVar) = let
380                  val globalBufferDecl =  CL.mkDecl(clMemoryTy,concat[RN.globalsVarName,"_cl"],NONE)                  val globalBufferDecl =  CL.mkDecl(clMemoryTy,concat[RN.globalsVarName,"_cl"],NONE)
381                  val globalBuffer = CL.mkAssign(CL.mkVar(concat[RN.globalsVarName,"_cl"]), CL.mkApply("clCreateBuffer",                val globalBuffer = CL.mkAssign(CL.mkVar(concat[RN.globalsVarName,"_cl"]),
382                                                                  [CL.mkVar contextVar,                      CL.mkApply("clCreateBuffer", [
383                            CL.mkVar contextVar,
384                                                                  CL.mkVar "CL_MEM_COPY_HOST_PTR",                                                                  CL.mkVar "CL_MEM_COPY_HOST_PTR",
385                                                                  CL.mkApply("sizeof",[CL.mkVar RN.globalsTy]),                                                                  CL.mkApply("sizeof",[CL.mkVar RN.globalsTy]),
386                                                                  CL.mkVar RN.globalsVarName,                                                                  CL.mkVar RN.globalsVarName,
387                                                                  CL.mkUnOp(CL.%&,CL.mkVar errVar)]))                          CL.mkUnOp(CL.%&,CL.mkVar errVar)
388                          ]))
389    
390          fun genDataBuffers([],_,_) = []          fun genDataBuffers([],_,_) = []
391            | genDataBuffers((var,nDims)::globals,contextVar,errVar) = let            | genDataBuffers((var,nDims)::globals,contextVar,errVar) = let
392          (* FIXME: use CL constructors to  build expressions (not strings) *)          (* FIXME: use CL constructors to  build expressions (not strings) *)
393                    val size = if nDims = 1 then                val size = if nDims = 1
394                                          CL.mkBinOp(CL.mkApply("sizeof",[CL.mkVar "float"]), CL.#*,                      then CL.mkBinOp(CL.mkApply("sizeof",[CL.mkVar "float"]), CL.#*,
395                                           CL.mkIndirect(CL.mkVar var, "size[0]"))                                           CL.mkIndirect(CL.mkVar var, "size[0]"))
396                                          else if nDims = 2 then                                          else if nDims = 2 then
397                                          CL.mkBinOp(CL.mkApply("sizeof",[CL.mkVar "float"]), CL.#*,                                          CL.mkBinOp(CL.mkApply("sizeof",[CL.mkVar "float"]), CL.#*,
# Line 443  Line 451 
451          end          end
452    
453        (* generates the globals buffers and arguments function *)        (* generates the globals buffers and arguments function *)
454          fun genGlobal_Buffers_Args (imgGlobals) = let          fun genGlobalBuffersArgs (imgGlobals) = let
455              (* Delcare opencl setup objects *)              (* Delcare opencl setup objects *)
456                val errVar = "err"                val errVar = "err"
457                val imgDataSizeVar = "image_dataSize"                val imgDataSizeVar = "image_dataSize"
# Line 452  Line 460 
460                                                           CL.PARAM([],CL.T_Named("cl_kernel"), "kernel"),                                                           CL.PARAM([],CL.T_Named("cl_kernel"), "kernel"),
461                                                           CL.PARAM([],CL.T_Named("int"), "argStart")                                                           CL.PARAM([],CL.T_Named("int"), "argStart")
462                      ]                      ]
   
   
463              val clGlobalBuffers = getGlobalDataBuffers(!imgGlobals, "context","err")              val clGlobalBuffers = getGlobalDataBuffers(!imgGlobals, "context","err")
   
464              val clGlobalArguments = genGlobalArguments(!imgGlobals,"argStart","kernel","err")              val clGlobalArguments = genGlobalArguments(!imgGlobals,"argStart","kernel","err")
   
465                  (* Body put all the statments together *)                  (* Body put all the statments together *)
466                  val body =  clGlobalBuffers @ clGlobalArguments                  val body =  clGlobalBuffers @ clGlobalArguments
467                  in                  in
# Line 469  Line 473 
473                  CL.PARAM([], CL.T_Ptr(CL.T_Named RN.globalsTy), concat[RN.globalsVarName]) ::                  CL.PARAM([], CL.T_Ptr(CL.T_Named RN.globalsTy), concat[RN.globalsVarName]) ::
474                  CL.PARAM([], CL.T_Ptr(CL.T_Named (RN.imageTy tyname)),RN.addBufferSuffix name) ::                  CL.PARAM([], CL.T_Ptr(CL.T_Named (RN.imageTy tyname)),RN.addBufferSuffix name) ::
475                  CL.PARAM([], CL.T_Ptr(CL.voidTy),RN.addBufferSuffixData name) ::                  CL.PARAM([], CL.T_Ptr(CL.voidTy),RN.addBufferSuffixData name) ::
476                  genKeneralGlobalParams(rest)                genKeneralGlobalParams rest
477              | genKeneralGlobalParams [] = []
           | genKeneralGlobalParams ([]) = []  
478    
479          (*generate code for intilizing kernel global data *)          (*generate code for intilizing kernel global data *)
480          fun initKernelGlobals (globals,imgGlobals) = let          fun initKernelGlobals (globals,imgGlobals) = let
481                  fun initGlobalStruct ({name,target as TargetUtil.TARGET_CL,globalTy}::rest) =  (* FIXME: should use List.map here *)
482                                  CL.mkAssign(CL.mkVar name, CL.mkIndirect(CL.mkVar RN.globalsVarName, name)) ::                fun initGlobalStruct ({hostTy, gpuTy, var}::rest) =
483                                  initGlobalStruct(rest)                      CL.mkAssign(CL.mkVar var, CL.mkIndirect(CL.mkVar RN.globalsVarName, var)) ::
484                    | initGlobalStruct ( _::rest) = initGlobalStruct(rest)                      initGlobalStruct rest
485                    | initGlobalStruct([]) = []                  | initGlobalStruct [] = []
   
486                  fun initGlobalImages((name,tyname)::rest) =                  fun initGlobalImages((name,tyname)::rest) =
487                                  CL.mkAssign(CL.mkVar name, CL.mkVar (RN.addBufferSuffix name)) ::                                  CL.mkAssign(CL.mkVar name, CL.mkVar (RN.addBufferSuffix name)) ::
488                                  CL.mkAssign(CL.mkIndirect(CL.mkVar name,"data"),CL.mkVar (RN.addBufferSuffixData name)) ::                                  CL.mkAssign(CL.mkIndirect(CL.mkVar name,"data"),CL.mkVar (RN.addBufferSuffixData name)) ::
489                                  initGlobalImages(rest)                      initGlobalImages rest
490                    | initGlobalImages([]) = []                    | initGlobalImages [] = []
491                  in                  in
492                    initGlobalStruct(globals) @ initGlobalImages(imgGlobals)                  initGlobalStruct globals @ initGlobalImages(imgGlobals)
493                  end                  end
494    
495          (* generate the main kernel function for the .cl file *)          (* generate the main kernel function for the .cl file *)
496          fun genKernelFun(Strand{name, tyName, state, output, code,...},nDims,globals,imgGlobals) = let          fun genKernelFun (strand, nDims, globals, imgGlobals) = let
497                  val Strand{name, tyName, state, output, code,...} = strand
498                   val fName = RN.kernelFuncName;                   val fName = RN.kernelFuncName;
499                   val inState = "strand_in"                   val inState = "strand_in"
500                   val outState = "strand_out"                   val outState = "strand_out"
# Line 501  Line 504 
504                        CL.PARAM(["__global"], CL.intTy, "width")                        CL.PARAM(["__global"], CL.intTy, "width")
505                      ] @ genKeneralGlobalParams(!imgGlobals)                      ] @ genKeneralGlobalParams(!imgGlobals)
506                    val thread_ids = if nDims = 1                    val thread_ids = if nDims = 1
507                          then [CL.mkDecl(CL.intTy, "x", SOME(CL.I_Exp(CL.mkInt(0, CL.intTy)))),                      then [
508                                    CL.mkAssign(CL.mkVar "x",CL.mkApply(RN.getGlobalThreadId,[CL.mkInt(0,CL.intTy)]))]                          CL.mkDecl(CL.intTy, "x", SOME(CL.I_Exp(CL.mkInt(0, CL.intTy)))),
509                          else                          CL.mkAssign(CL.mkVar "x",CL.mkApply(RN.getGlobalThreadId,[CL.mkInt(0,CL.intTy)]))
510                                  [CL.mkDecl(CL.intTy, "x", SOME(CL.I_Exp(CL.mkInt(0, CL.intTy)))),                        ]
511                        else [
512                            CL.mkDecl(CL.intTy, "x", SOME(CL.I_Exp(CL.mkInt(0, CL.intTy)))),
513                                   CL.mkDecl(CL.intTy, "y", SOME(CL.I_Exp(CL.mkInt(0, CL.intTy)))),                                   CL.mkDecl(CL.intTy, "y", SOME(CL.I_Exp(CL.mkInt(0, CL.intTy)))),
514                                    CL.mkAssign(CL.mkVar "x",  CL.mkApply(RN.getGlobalThreadId,[CL.mkInt(0,CL.intTy)])),                                    CL.mkAssign(CL.mkVar "x",  CL.mkApply(RN.getGlobalThreadId,[CL.mkInt(0,CL.intTy)])),
515                                    CL.mkAssign(CL.mkVar "y",CL.mkApply(RN.getGlobalThreadId,[CL.mkInt(1,CL.intTy)]))]                          CL.mkAssign(CL.mkVar "y",CL.mkApply(RN.getGlobalThreadId,[CL.mkInt(1,CL.intTy)]))
516                          ]
517                    val strandDecl = [CL.mkDecl(CL.T_Named tyName, inState, NONE),                val strandDecl = [
518                        CL.mkDecl(CL.T_Named tyName, inState, NONE),
519                                                          CL.mkDecl(CL.T_Named tyName, outState,NONE)]                                                          CL.mkDecl(CL.T_Named tyName, outState,NONE)]
520                    val strandObjects  = if nDims = 1                    val strandObjects  = if nDims = 1
521                          then [CL.mkAssign( CL.mkVar inState, CL.mkSubscript(CL.mkVar "selfIn",CL.mkStr "x")),                          then [
522                                    CL.mkAssign(CL.mkVar outState,CL.mkSubscript(CL.mkVar "selfOut",CL.mkStr "x"))]                              CL.mkAssign( CL.mkVar inState, CL.mkSubscript(CL.mkVar "selfIn", CL.mkStr "x")),
523                                CL.mkAssign(CL.mkVar outState,CL.mkSubscript(CL.mkVar "selfOut", CL.mkStr "x"))
524                              ]
525                          else let                          else let
526                                  val index = CL.mkBinOp(CL.mkBinOp(CL.mkVar "x",CL.#*,CL.mkVar "width"),CL.#+,CL.mkVar "y")                                  val index = CL.mkBinOp(CL.mkBinOp(CL.mkVar "x",CL.#*,CL.mkVar "width"),CL.#+,CL.mkVar "y")
527                                  in                                  in
528                                          [CL.mkAssign(CL.mkVar inState, CL.mkSubscript(CL.mkVar "selfIn",index)),                                          [CL.mkAssign(CL.mkVar inState, CL.mkSubscript(CL.mkVar "selfIn",index)),
529                                           CL.mkAssign(CL.mkVar outState,CL.mkSubscript(CL.mkVar "selfOut",index))]                                           CL.mkAssign(CL.mkVar outState,CL.mkSubscript(CL.mkVar "selfOut",index))]
530                                  end                                  end
   
   
531                    val status = CL.mkDecl(CL.intTy, "status", SOME(CL.I_Exp(CL.mkInt(0, CL.intTy))))                    val status = CL.mkDecl(CL.intTy, "status", SOME(CL.I_Exp(CL.mkInt(0, CL.intTy))))
532                    val local_vars =  thread_ids @ initKernelGlobals(!globals,!imgGlobals)  @ strandDecl @ strandObjects @ [status]                    val local_vars =  thread_ids @ initKernelGlobals(!globals,!imgGlobals)  @ strandDecl @ strandObjects @ [status]
533                    val while_exp = CL.mkBinOp(CL.mkBinOp(CL.mkVar "status",CL.#!=, CL.mkVar RN.kStabilize),CL.#||,CL.mkBinOp(CL.mkVar "status", CL.#!=, CL.mkVar RN.kDie))                    val while_exp = CL.mkBinOp(CL.mkBinOp(CL.mkVar "status",CL.#!=, CL.mkVar RN.kStabilize),CL.#||,CL.mkBinOp(CL.mkVar "status", CL.#!=, CL.mkVar RN.kDie))
534                    val while_body = [CL.mkAssign(CL.mkVar "status", CL.mkApply(RN.strandUpdate name,[ CL.mkUnOp(CL.%&,CL.mkVar inState), CL.mkUnOp(CL.%&,CL.mkVar outState)])),                val whileBody = CL.mkBlock [
535                                                          CL.mkCall(RN.strandStabilize name,[ CL.mkUnOp(CL.%&,CL.mkVar inState),  CL.mkUnOp(CL.%&,CL.mkVar outState)])]                        CL.mkAssign(CL.mkVar "status",
536                            CL.mkApply(RN.strandUpdate name,
537                    val whileBlock = [CL.mkWhile(while_exp,CL.mkBlock while_body)]                            [CL.mkUnOp(CL.%&,CL.mkVar inState), CL.mkUnOp(CL.%&,CL.mkVar outState)])),
538                          CL.mkCall(RN.strandStabilize name,
539                            [CL.mkUnOp(CL.%&,CL.mkVar inState), CL.mkUnOp(CL.%&,CL.mkVar outState)])
540                        ]
541                  val whileBlock = [CL.mkWhile(while_exp, whileBody)]
542                    val body = CL.mkBlock(local_vars  @ whileBlock)                    val body = CL.mkBlock(local_vars  @ whileBlock)
543                  in                  in
544                     CL.D_Func(["__kernel"], CL.voidTy, fName, params, body)                     CL.D_Func(["__kernel"], CL.voidTy, fName, params, body)
545                  end                  end
546          (* generate a global structure from the globals *)          (* generate a global structure from the globals *)
547          fun genGlobalStruct(target,globals) = let          fun genGlobalStruct (targetTy, globals) = let
548                   fun getGlobals(_, []) = []                val globs = List.map (fn (x : mirror_var) => (targetTy x, #var x)) globals
                         | getGlobals(target',{name,globalTy,target}::rest) =  
                                 if target = target' then  
                                 (globalTy,name)::getGlobals(target',rest)  
                                 else  
                                 getGlobals(target',rest)  
549                   in                   in
550                          CL.D_StructDef(getGlobals(target,globals),RN.globalsTy)                  CL.D_StructDef(globs, RN.globalsTy)
551                  end
552            fun genGlobals (declFn, targetTy, globals) = let
553                  fun doVar (x : mirror_var) = declFn (CL.D_Var([], targetTy x, #var x, NONE))
554                  in
555                    List.app doVar globals
556                    end                    end
   
    fun genGlobals(_,_, []) =  
                         ()  
           | genGlobals(declFun, target',{name,globalTy,target}::rest) =  
                         if target = target' then  
                            (declFun (CL.D_Var([], globalTy, name, NONE));  
                            genGlobals (declFun,target',rest))  
                         else  
                            genGlobals (declFun,target',rest)  
557    
558          fun genSrc (baseName, Prog{double,globals, topDecls, strands, initially,imgGlobals,numDims,...}) = let          fun genSrc (baseName, Prog{double,globals, topDecls, strands, initially,imgGlobals,numDims,...}) = let
559                val clFileName = OS.Path.joinBaseExt{base=baseName, ext=SOME "cl"}                val clFileName = OS.Path.joinBaseExt{base=baseName, ext=SOME "cl"}
# Line 576  Line 576 
576                      "#define DIDEROT_TARGET_CL",                      "#define DIDEROT_TARGET_CL",
577                      "#include \"Diderot/cl-diderot.h\""                      "#include \"Diderot/cl-diderot.h\""
578                    ]));                    ]));
579                  genGlobals(clppDecl,TargetUtil.TARGET_CL,!globals);                  genGlobals (clppDecl, #gpuTy, !globals);
580                  clppDecl (genGlobalStruct (TargetUtil.TARGET_CL,!globals));                  clppDecl (genGlobalStruct (#gpuTy, !globals));
581                  clppDecl (genStrandTyDef (strand));                  clppDecl (genStrandTyDef(#gpuTy, strand));
582                  List.app clppDecl (!code);                  List.app clppDecl (!code);
583                  clppDecl (genKernelFun (strand,!numDims,globals,imgGlobals));                  clppDecl (genKernelFun (strand,!numDims,globals,imgGlobals));
584    
585                (* Generate the Host file .c *)                (* Generate the Host C file *)
586                  cppDecl (CL.D_Verbatim([                  cppDecl (CL.D_Verbatim([
587                      if double                      if double
588                        then "#define DIDEROT_DOUBLE_PRECISION"                        then "#define DIDEROT_DOUBLE_PRECISION"
# Line 590  Line 590 
590                      "#define DIDEROT_TARGET_CL",                      "#define DIDEROT_TARGET_CL",
591                      "#include \"Diderot/diderot.h\""                      "#include \"Diderot/diderot.h\""
592                    ]));                    ]));
593                  genGlobals(cppDecl,TargetUtil.TARGET_C,!globals);                  genGlobals (cppDecl, #hostTy, !globals);
594                  cppDecl (genGlobalStruct (TargetUtil.TARGET_C,!globals));                  cppDecl (genGlobalStruct (#hostTy, !globals));
595                  cppDecl (genStrandTyDef (strand));                  cppDecl (genStrandTyDef (#gpuTy, strand));
596                  cppDecl  (!init_code);                  cppDecl  (!init_code);
597                  cppDecl (genStrandPrint(strand));                  cppDecl (genStrandPrint strand);
598                  List.app cppDecl (List.rev (!topDecls));                  List.app cppDecl (List.rev (!topDecls));
599                  cppDecl (genGlobal_Buffers_Args (imgGlobals));                  cppDecl (genGlobalBuffersArgs (imgGlobals));
600                  cppDecl (!initially);                  cppDecl (!initially);
601                  PrintAsC.close cppStrm;                  PrintAsC.close cppStrm;
602                  PrintAsCL.close clppStrm;                  PrintAsCL.close clppStrm;

Legend:
Removed from v.1306  
changed lines
  Added in v.1307

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