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

SCM Repository

[diderot] View of /branches/vis15/src/compiler/options/options.sml
ViewVC logotype

View of /branches/vis15/src/compiler/options/options.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4588 - (download) (annotate)
Mon Sep 19 02:13:20 2016 UTC (2 years, 11 months ago) by jhr
File size: 11842 byte(s)
  working on merge: added integer-typed reductions (min, max, product, and sum), and
  functions numActive, numStable, and numStrands to basis.
(* options.sml
 *
 * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
 *
 * COPYRIGHT (c) 2015 The University of Chicago
 * All rights reserved.
 *)

structure Options : sig

  (* raised if parsing command-line args hits an error (e.g., missing option, syntax, ...).
   * The string is an error message.
   *)
    exception Usage of string

  (* parse the command-line args *)
    val parseCmdLine : string list -> {
            help : bool option,         (* "-h" and "--help" ==> SOME false; "-H" ==> SOME true. *)
            version : bool,             (* "--version" specified? *)
            about : bool,               (* "--about" specified? *)
            defs : string list,         (* input-variable definitions *)
            target : TargetOptions.t,   (* collected infromation about the target *)
            file : string               (* source file *)
          }

  (* return a usage message.  The boolean controls whether all options should be
   * included (true ==> long; false ==> short).
   *)
    val usage : string * bool -> string

  end = struct

    structure G = GetOpt
    structure P = OS.Path
    structure Tgt = TargetOptions

    exception Usage of string

  (* option flags that are set by getOpt *)
    val helpFlg = ref(NONE : bool option)       (* SOME false -- short help; SOME true -- long help *)
    val aboutFlg = ref false
    val longHelp = ref false
    val versionFlg = ref false
    val debugFlg = ref false
    val doubleFlg = ref false
    val longIntFlg = ref false
    val scalarFlg = ref false
    val outputOpt : string option ref = ref NONE
    val standaloneFlg = ref false
    val snapshotFlg = ref false
    val prefix : string option ref = ref NONE
    val platform = ref Tgt.SEQUENTIAL
    val bspFlg = ref false

    fun mkOpt ctl = let
          val name = if Controls.get ctl
                then "disable-" ^ Controls.name ctl
                else Controls.name ctl
          in
            Controls.mkOptionFlag {ctl = ctl, short = "", long = SOME name}
          end

  (* create the target option descriptor. *)
    local
      val desc = if Paths.cudaEnabled then ["  cuda       -- generate CUDA code"] else []
      val desc = if Paths.clEnabled then "  opencl     -- generate OpenCL code" :: desc else desc
      val desc = "  parallel   -- generate parallel code" :: desc
      val desc = "  sequential -- generate sequential code (default)" :: desc
      val desc = "specify the target platform:" :: desc
      fun parseTargetOpt "c" = (platform := Tgt.SEQUENTIAL)
        | parseTargetOpt "sequential" = (platform := Tgt.SEQUENTIAL)
        | parseTargetOpt "parallel" = (platform := Tgt.PARALLEL)
        | parseTargetOpt "pthread" = (platform := Tgt.PARALLEL)
        | parseTargetOpt "cl" = if Paths.clEnabled
            then (platform := Tgt.OPENCL)
            else raise Usage "cl target not supported by this version"
        | parseTargetOpt "opencl" = if Paths.clEnabled
            then (platform := Tgt.OPENCL)
            else raise Usage "cl target not supported by this version"
        | parseTargetOpt "cuda" = if Paths.cudaEnabled
            then (platform := Tgt.CUDA)
            else raise Usage "cuda target not supported by this version"
        | parseTargetOpt opt = raise Usage(concat["unrecognized target \"", opt, "\""])
    in
    val targetOptDesc = {
            short = "",
            long = ["target"],
            desc = G.ReqArg(parseTargetOpt, "target"),
            help = String.concatWith "\n" desc
          }
    end

    fun setFlag (flg, value) = G.NoArg(fn () => (flg := value))

  (* the short list of options, which does not include the compiler controls *)
    val optionList = [
            { short = "h", long = ["help"],
              desc = setFlag (helpFlg, SOME false),
              help = "print command-line options"
            },
            { short = "H", long = [],
              desc = setFlag (helpFlg, SOME true),
              help = "print all command-line options (including compiler controls)"
            },
            { short = "", long = ["version"],
              desc = setFlag (versionFlg, true),
              help = "show the compiler version"
            },
            { short = "", long = ["about"],
              desc = setFlag (aboutFlg, true),
              help = "information about the Diderot language and compiler"
            },
            { short = "", long = ["exec"],
              desc = setFlag (standaloneFlg, true),
              help = "generate a standalone executable"
            },
            { short = "o", long = ["output"],
              desc = G.ReqArg(fn s => outputOpt := SOME s, "file"),
              help = "specify the executable file name"
            },
            { short = "", long = ["namespace"],
              desc = G.ReqArg(fn s => prefix := SOME s, "prefix"),
              help = "specify namespace prefix for generated code"
            },
            { short = "", long = ["snapshot"],
              desc = setFlag (snapshotFlg, true),
              help = "generate code to get a snapshot of strand states"
            },
            { short = "g", long = ["debug"],
              desc = setFlag (debugFlg, true),
              help = "enable debugging information in executable"
            },
            { short = "", long = ["double"],
              desc = setFlag (doubleFlg, true),
              help = "use double-precision floats for reals"
            },
            { short = "", long = ["long-int"],
              desc = setFlag (longIntFlg, true),
              help = "use 64-bits for ints"
            },
            { short = "", long = ["scalar"],
              desc = setFlag (scalarFlg, true),
              help = "do not generate vectorized code"
            },
            Controls.mkOptionFlag {ctl = Ctl.enableLog, short = "", long = SOME "log"},
            Controls.mkOptionFlag {ctl = Ctl.collectStats, short = "", long = SOME "stats"},
            Controls.mkOptionFlag {ctl = Ctl.verbose, short = "", long = SOME "verbose"},
            targetOptDesc
          ]

  (* create the list of options that control compiler internals *)
    val ctlOptions = let
          val optimizeFlags = List.map mkOpt Ctl.optimizeControls
          val dumpFlags = List.map mkOpt Ctl.dumpControls @ [
                  { short = "", long = ["dump-cfg"],
                    desc = setFlag (Ctl.dumpCFG, true),
                    help = "dump out all CFG representations to the log file"
                  },
                  { short = "", long = ["dump-all"],
                    desc = setFlag (Ctl.dumpAll, true),
                    help = "dump out all intermediate representations to the log file"
                  },
                  { short = "", long = ["show-cfg-labels"],
                    desc = setFlag (Ctl.compactCFG, false),
                    help = "show the labels of all CFG nodes"
                  },
                  { short = "", long = ["log-ticks"],
                    desc = setFlag (Stats.logTicks, false),
                    help = "log each optimization tick as it is recorded"
                  }
                ]
          val checkFlags = List.map mkOpt Ctl.checkControls @ [
                { short = "", long = ["check-all"],
                  desc = setFlag (Ctl.checkAll, true),
                  help = "always check intermediate representations"
                }]
          in
            { short = "", long = ["force-bsp"],
                desc = setFlag (bspFlg, true),
                help = "execute strands in BSP mode"
              } :: optimizeFlags @ dumpFlags @ checkFlags
          end

    fun mkTargetDesc (srcFile) : Tgt.t = let
          val (outDir, outBase) = (case !outputOpt
                 of NONE => let
                      val {dir, file} = P.splitDirFile srcFile
                      in
                        case P.splitBaseExt file
                         of {base, ext=SOME "diderot"} => (dir, base)
                          | {base, ext=SOME "ddro"} => (dir, base)
                          | _ => (dir, file)
                        (* end case *)
                      end
                  | SOME outFile => let
                      val {dir, file} = P.splitDirFile outFile
                      in
                        if !standaloneFlg
                          then (dir, file)
                          else (case P.splitBaseExt file
                             of {base, ext=SOME "o"} => (dir, base)
                              | {base, ext=SOME "obj"} => (dir, base)
                              | _ => (dir, file)
                            (* end case *))
                      end
                (* end case *))
        (* get the namespace and check that it is legal *)
          val namespace = (case !prefix
                 of NONE => "Diderot"
                  | SOME "diderot" => raise Usage "namespace \"diderot\" is reserved"
                  | SOME ns => (case String.explode ns
                       of [] => raise Usage "invalid empty namespace specifier"
                        | c::cs => let
                            fun isAlpha #"_" = true | isAlpha c = Char.isAlpha c
                            fun isAlphaNum #"_" = true | isAlphaNum c = Char.isAlphaNum c
                            in
                              if isAlpha c andalso List.all isAlphaNum cs
                                then ns
                                else raise Usage "invalid namespace specifier"
                            end
                      (* end case *))
                (* end case *))
	(* if necessary, set the Diderot integer size to long *)
	  val () = if !longIntFlg then IntLit.setDiderotLongInt() else ()
          in {
            srcFile = srcFile,
            outDir = outDir,
            outBase = outBase,
            exec = !standaloneFlg,
            snapshot = not(!standaloneFlg) andalso !snapshotFlg,
            platform = !platform,
            namespace = namespace,
            double = !doubleFlg,
            longint = !longIntFlg,
            scalar = !scalarFlg,
            debug = !debugFlg,
            bsp = !bspFlg
          } end

    fun parseCmdLine [] = {
            help = SOME false,
            version = false,
            about = false,
            defs = [],
            target = mkTargetDesc "",
            file = ""
          }
      | parseCmdLine args = let
        (* first we filter out any variable definitions *)
          val (defs, rest) = List.partition CmdLineConstants.isCmdLineConst args
          val (opts, files) = G.getOpt {
                  argOrder = G.RequireOrder,
                  options = optionList @ ctlOptions,
                  errFn = fn s => raise Usage s
                } args
        (* figure out filename pieces *)
          val srcFile = if isSome(!helpFlg) orelse !versionFlg orelse !aboutFlg
                then ""
                else (case files
                   of [] => raise Usage "missing file argument"
                    | [f] => f
                    | _ => raise Usage "too many files"
                  (* end case *))
          in {
            help = !helpFlg,
            version = !versionFlg,
            about = !aboutFlg,
            defs = defs,
            target = mkTargetDesc srcFile,
            file = srcFile
          } end

    fun usage (cmd, long) = let
          val hdr = concat[
                  "usage: ", cmd, " [options] file.diderot\n",
                  "  Version: ", Version.message, "\n",
                  "  Options:"
                ]
          in
            if long
              then G.usageInfo {header = hdr, options = optionList @ ctlOptions}
              else G.usageInfo {header = hdr, options = optionList}
          end

  end

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