accelerate-examples-0.12.0.0: examples/tests/primitives/Gather.hs
{-# LANGUAGE FlexibleContexts #-}
module Gather where
import Random
import System.Random.MWC
import Data.Array.Unboxed
import Data.Array.Accelerate as Acc hiding ((!))
import Prelude as P
-- Tests
-- -----
gatherAcc :: Vector Int -> Vector Float -> Acc (Vector Float)
gatherAcc mapV inputV = Acc.gather (use mapV) (use inputV)
gatherIfAcc :: Vector Int -> Vector Int -> Vector Float -> Vector Float -> Acc (Vector Float)
gatherIfAcc mapV maskV defaultV inputV
= Acc.gatherIf (use mapV) (use maskV) evenAcc (use defaultV) (use inputV)
evenAcc :: Exp Int -> Exp Bool
evenAcc v = (v `mod` 2) ==* 0
gatherRef :: UArray Int Int -> UArray Int Float -> UArray Int Float
gatherRef mapV inputV = amap (\ix -> inputV ! ix) mapV
gatherIfRef :: UArray Int Int -> UArray Int Int -> UArray Int Float -> UArray Int Float -> UArray Int Float
gatherIfRef mapV maskV defaultV inputV
= listArray (bounds mapV)
$ P.map (\(mIx, mV, dV) -> if evenRef mV then (inputV ! mIx) else dV)
$ P.zip3 mapL maskL defaultL
where
mapL = elems mapV
maskL = elems maskV
defaultL = elems defaultV
evenRef :: Int -> Bool
evenRef = even
-- Main
-- ----
run :: String -> Int -> IO (() -> UArray Int Float, () -> Acc (Vector Float))
run alg n = withSystemRandom $ \gen -> do
vec <- randomUArrayR (-1, 1) gen n
vec' <- convertUArray vec
mapV <- randomUArrayR (0, n - 1) gen n
mapV' <- convertUArray mapV
maskV <- randomUArrayR (0, n) gen n
maskV' <- convertUArray maskV
defaultV <- randomUArrayR (-1, 1) gen n
defaultV' <- convertUArray defaultV
--
let go f g = return (run_ref f vec, run_acc g vec')
case alg of
"gather" -> go (gatherRef mapV) (gatherAcc mapV')
"gather-if" -> go (gatherIfRef mapV maskV defaultV) (gatherIfAcc mapV' maskV' defaultV')
x -> error $ "unknown variant: " ++ x
where
{-# NOINLINE run_ref #-}
run_ref f xs () = f xs
run_acc f xs () = f xs