accelerate-examples-0.12.0.0: examples/fluid/src/Config.hs
{-# LANGUAGE CPP, TemplateHaskell, PatternGuards #-}
--
-- Configuration parameters
--
module Config (
Options,
viscosity, diffusion, densityBMP, velocityBMP, simulationWidth,
simulationHeight, displayScale, displayFramerate, optBench,
processArgs, run, run1
) where
import Data.Label
import System.Exit
import System.Console.GetOpt
import Data.Array.Accelerate ( Acc, Arrays )
import qualified Data.Array.Accelerate.Interpreter as I
#ifdef ACCELERATE_CUDA_BACKEND
import qualified Data.Array.Accelerate.CUDA as CUDA
#endif
data Backend
= Interpreter
#ifdef ACCELERATE_CUDA_BACKEND
| CUDA
#endif
deriving (Show, Bounded)
data Options = Options
{
-- simulation
_viscosity :: Float
, _diffusion :: Float
-- visualisation
, _densityBMP :: Maybe FilePath
, _velocityBMP :: Maybe FilePath
, _simulationWidth :: Int
, _simulationHeight :: Int
, _displayScale :: Int
, _displayFramerate :: Int
-- misc
, _optBackend :: Backend
, _optBench :: Bool
, _optHelp :: Bool
}
deriving Show
$(mkLabels [''Options])
defaultOptions :: Options
defaultOptions = Options
{ _viscosity = 0
, _diffusion = 0
, _densityBMP = Nothing
, _velocityBMP = Nothing
, _simulationWidth = 250
, _simulationHeight = 250
, _displayScale = 2
, _displayFramerate = 20
, _optBackend = maxBound
, _optBench = False
, _optHelp = False
}
-- Execute an Accelerate expression using the selected backend
--
run :: Arrays a => Options -> Acc a -> a
run opts = case _optBackend opts of
Interpreter -> I.run
#ifdef ACCELERATE_CUDA_BACKEND
CUDA -> CUDA.run
#endif
run1 :: (Arrays a, Arrays b) => Options -> (Acc a -> Acc b) -> a -> b
run1 opts f = case _optBackend opts of
Interpreter -> head . I.stream f . return
#ifdef ACCELERATE_CUDA_BACKEND
CUDA -> CUDA.run1 f
#endif
-- Process command line arguments
--
options :: [OptDescr (Options -> Options)]
options =
[ Option [] ["interpreter"] (NoArg (set optBackend Interpreter))
"reference implementation (sequential)"
#ifdef ACCELERATE_CUDA_BACKEND
, Option [] ["cuda"] (NoArg (set optBackend CUDA))
"implementation for NVIDIA GPUs (parallel)"
#endif
, Option [] ["viscosity"] (ReqArg (set viscosity . read) "FLOAT")
$ "viscosity for velocity dampening " ++ def viscosity
, Option [] ["diffusion"] (ReqArg (set diffusion . read) "FLOAT")
$ "diffusion rate for mass dispersion " ++ def diffusion
, Option [] ["width"] (ReqArg (set simulationWidth . read) "INT")
$ "grid width for simulation " ++ def simulationWidth
, Option [] ["height"] (ReqArg (set simulationHeight . read) "INT")
$ "grid height for simulation " ++ def simulationHeight
, Option [] ["scale"] (ReqArg (set displayScale . read) "INT")
$ "feature size of visualisation " ++ def displayScale
, Option [] ["framerate"] (ReqArg (set displayFramerate . read) "INT")
$ "frame rate for visualisation " ++ def displayFramerate
, Option [] ["bmp-density"] (ReqArg (set densityBMP . Just) "FILE.bmp")
"file for initial fluid density"
, Option [] ["bmp-velocity"] (ReqArg (set velocityBMP . Just) "FILE.bmp")
"file for initial fluid velocity"
--
, Option [] ["benchmark"] (NoArg (set optBench True))
"benchmark instead of displaying animation (False)"
, Option "h?" ["help"] (NoArg (set optHelp True))
"show help message"
]
where
parens s = "(" ++ s ++ ")"
def f = parens (show (get f defaultOptions))
processArgs :: [String] -> IO (Options, [String])
processArgs argv =
case getOpt' Permute options argv of
(o,_,n,[]) -> case foldl (flip id) defaultOptions o of
opts | False <- get optHelp opts -> return (opts, n)
opts | True <- get optBench opts -> return (opts, "--help":n)
_ -> putStrLn (helpMsg []) >> exitSuccess
(_,_,_,err) -> error (helpMsg err)
where
helpMsg err = concat err ++ usageInfo header options ++ footer
header = unlines
[ "accelerate-fluid (c) 2011 Trevor L. McDonell"
, ""
, "Usage: accelerate-fluid [OPTIONS]"
]
footer = unlines
[ ""
, "Runtime usage:"
, ""
, " click add density sources to the image"
, " shift-click add velocity sources"
, " r reset the image"
, " d toggle display of density field"
, " v toggle display of velocity field lines"
]