packages feed

accelerate-examples-0.2.0.0: tests/primitives/Backpermute.hs

{-# LANGUAGE TypeOperators #-}

module Backpermute where

import Random

import Control.Monad
import Control.Exception
import System.Random.MWC
import Data.Array.Unboxed
import Data.Array.Accelerate as Acc
import Prelude               as P


-- Tests
-- -----

reverseAcc :: Vector Float -> Acc (Vector Float)
reverseAcc xs =
  let xs' = use xs
      len = unindex1 (shape xs')
  in
  backpermute (shape xs') (\ix -> index1 $ len - (unindex1 ix) - 1) xs'

reverseRef :: UArray Int Float -> UArray Int Float
reverseRef xs = listArray (bounds xs) (reverse (elems xs))


transposeAcc :: Acc.Array DIM2 Float -> Acc (Acc.Array DIM2 Float)
transposeAcc mat =
  let mat' = use mat
      swap = lift1 $ \(Z:.x:.y) -> Z:.y:.x :: Z:.Exp Int:.Exp Int
  in
  backpermute (swap $ shape mat') swap mat'

transposeRef :: UArray (Int,Int) Float -> UArray (Int,Int) Float
transposeRef mat =
  let swap (x,y) = (y,x)
      (u,v)      = bounds mat
  in
  array (swap u, swap v) [(swap ix, e) | (ix, e) <- assocs mat]


-- 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
  --
  let go f g = return (\() -> f vec, \() -> g vec')
  case alg of
    "reverse" -> go reverseRef reverseAcc
    _         -> error $ "unknown variant: " ++ alg

run2d :: String -> Int -> IO (() -> UArray (Int,Int) Float, () -> Acc (Acc.Array DIM2 Float))
run2d alg n = withSystemRandom $ \gen -> do
  let n'    = P.round $ sqrt (P.fromIntegral n :: Double)
      (u,v) = (n'*2, n'`div`2)
  mat  <- listArray ((0,0), (u-1,v-1)) `fmap` replicateM (u*v) (uniformR (-1,1) gen)
  mat' <- let m = fromIArray mat :: Acc.Array DIM2 Float
          in  evaluate (m `Acc.indexArray` (Z:.0:.0)) >> return m
  --
  let go f g = return (\() -> f mat, \() -> g mat')
  case alg of
    "transpose" -> go transposeRef transposeAcc
    _           -> error $ "unknown variant: " ++ alg