accelerate-0.8.1.0: examples/simple/src/Main.hs
{-# LANGUAGE FlexibleContexts #-}
module Main where
import Prelude hiding (filter)
import DotP
import Filter
import Random
import SAXPY
import SMVM
import Data.Array.Accelerate (Acc)
import qualified Data.Array.Accelerate as Acc
import qualified Data.Array.Accelerate.CUDA as CUDA
import qualified Data.Array.Accelerate.Interpreter as Interp
import Data.Array.Unboxed (IArray, UArray, Ix, elems, indices, (!))
import System.Random.MWC (create, uniform, GenIO)
import Control.Exception (evaluate)
import Control.DeepSeq
import Criterion.Main
instance (Ix dim, IArray UArray e) => NFData (UArray dim e) where
rnf a = a ! head (indices a) `seq` ()
-- Generate a benchmark test iff the reference and accelerate tests succeed.
--
benchmark
:: (IArray UArray e, Ix dim, Acc.Ix dim, Acc.Elem e)
=> String
-> (e -> e -> Bool)
-> (() -> UArray dim e)
-> (() -> Acc (Acc.Array dim e))
-> IO Benchmark
benchmark name sim ref acc = do
putStr "Interpreter : " ; v1 <- validate sim (ref ()) (Acc.toIArray $ Interp.run (acc ()))
putStr "CUDA : " ; v2 <- validate sim (ref ()) (Acc.toIArray $ CUDA.run (acc ()))
if not (v1 && v2)
then return $ bgroup "" []
else return $ bgroup name
[ bench "ref" $ nf ref ()
, bench "cuda" $ whnf (CUDA.run . acc) ()
]
-- Tests
--
test_dotp :: GenIO -> Int -> IO Benchmark
test_dotp gen n = do
putStrLn $ "== Dot Product (n = " ++ shows n ") =="
xs <- randomVector gen id n
ys <- randomVector gen id n
xs' <- convertVector xs
ys' <- convertVector ys
benchmark "dotp" similar (run_ref xs ys) (run_acc xs' ys')
where
{-# NOINLINE run_ref #-}
run_ref x y () = dotp_ref x y
run_acc x y () = dotp x y
test_saxpy :: GenIO -> Int -> IO Benchmark
test_saxpy gen n = do
putStrLn $ "== SAXPY (n = " ++ shows n ") =="
xs <- randomVector gen id n
ys <- randomVector gen id n
xs' <- convertVector xs
ys' <- convertVector ys
alpha <- uniform gen
benchmark "saxpy" similar (run_ref alpha xs ys) (run_acc alpha xs' ys')
where
{-# NOINLINE run_ref #-}
run_ref alpha x y () = saxpy_ref alpha x y
run_acc alpha x y () = saxpy alpha x y
test_filter :: GenIO -> Int -> IO Benchmark
test_filter gen n = do
putStrLn $ "== Filter (n = " ++ shows n ") =="
xs <- randomVector gen id n :: IO (UArray Int Float)
xs' <- convertVector xs
benchmark "filter" similar (run_ref xs) (run_acc xs')
where
{-# NOINLINE run_ref #-}
run_ref x () = filter_ref (< 0.5) x
run_acc x () = filter (Acc.<* 0.5) x
test_smvm :: GenIO -> (Int,Int) -> (Int,Int) -> IO Benchmark
test_smvm gen (n,m) (rows,cols) = do
putStr $ "== SMVM (" ++ shows rows " x " ++ shows cols ", "
vec <- randomVector gen id cols
segd <- randomVector gen (\x -> (abs x `rem` (m-n)) + n) rows
let nnz = sum (elems segd)
putStrLn $ shows nnz " non-zeros) =="
inds <- randomVector gen (\x -> abs x `rem` cols) nnz
vals <- randomVector gen id nnz
segd' <- convertVector segd
vec' <- convertVector vec
mat' <- let v = Acc.fromList nnz (zip (elems inds) (elems vals))
in evaluate (v `Acc.indexArray` 0) >> return v
benchmark "smvm" similar (run_ref segd inds vals vec) (run_acc segd' mat' vec')
where
{-# NOINLINE run_ref #-}
run_ref d i x v () = smvm_ref (d, (i,x)) v
run_acc d x v () = smvm (d,x) v
-- Main
--
main :: IO ()
main = do
putStrLn "Data.Array.Accelerate: simple examples"
putStrLn "--------------------------------------"
gen <- create
defaultMain =<< sequence
[ test_dotp gen 100000
, test_saxpy gen 100000
, test_filter gen 10000
, test_smvm gen (0,42) (2400,400)
]