packages feed

accelerate-examples-0.2.0.0: tests/io/BlockCopy.hs

{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables, TypeOperators #-}

module BlockCopy where

-- standard libraries
import Prelude as P
import Foreign.Ptr
import Control.Monad
import Control.Exception

-- friends
import Data.Array.Accelerate
import Data.Array.Accelerate.IO

assertEqual :: (Eq a, Show a) => String -> a -> a -> IO ()
assertEqual preface expected actual =
  unless (actual == expected) (throw $ AssertionFailed msg)
  where
    msg = (if null preface then "" else preface ++ "\n")  ++
          "expected: " ++ show expected ++ "\n but got: " ++ show actual

run :: IO ()
run =
  mapM_ (\(msg,act) -> putStrLn ("test: " ++ msg) >> act)
    [ ("fromPtr Int",          testBlockCopyPrim)
    , ("fromPtr (Int,Double)", testBlockCopyTuples)
    , ("toPtr Int16",          testBlockCopyFromArrayInt16)
    , ("toPtr Int32",          testBlockCopyFromArrayInt32)
    , ("toPtr Int64",          testBlockCopyFromArrayInt64)
    , ("fromArray Int",        testBlockCopyFromArrayWithFunctions) ]


testBlockCopyPrim :: IO ()
testBlockCopyPrim = do
  ptr <- oneToTen
  (arr :: Vector Int32) <- fromPtr (Z :. 10) ((), ptr)
  assertEqual "Not equal" [1..10] (toList arr)

testBlockCopyTuples :: IO ()
testBlockCopyTuples = do
  intPtr    <- oneToTen
  doublePtr <- tenToOne
  (arr :: Vector (Int32, Double)) <- fromPtr (Z :. 10) (((), intPtr), doublePtr)
  assertEqual "Not equal" [ (x, P.fromIntegral (11 - x)) | x <- [1..10]] (toList arr)

testBlockCopyFromArrayWithFunctions :: IO ()
testBlockCopyFromArrayWithFunctions = do
  let n = 5^(3::Int)
  let (arr :: Array (Z:.Int:.Int:.Int) Int32) = fromList (Z:.5:.5:.5) [2*x | x <- [0..n-1]]
  ohi <- nInt32s (P.fromIntegral n)
  fromArray arr ((), memcpy ohi)
  b   <- isFilledWithEvens32 ohi (P.fromIntegral n)
  assertEqual "Not equal" 1 b

testBlockCopyFromArrayInt16 :: IO ()
testBlockCopyFromArrayInt16 = do
  let n = 50
  let (arr :: Vector Int16) = fromList (Z:.n) [2 * P.fromIntegral x | x <- [0..n-1]]
  ohi <- nInt16s (P.fromIntegral n)
  toPtr arr ((), ohi)
  b   <- isFilledWithEvens16 ohi (P.fromIntegral n)
  assertEqual "Not equal" 1 b

testBlockCopyFromArrayInt32 :: IO ()
testBlockCopyFromArrayInt32 = do
  let (arr :: Array (Z:.Int:.Int) Int32) = fromList (Z:.10:.10) [2*x | x <- [0..99]]
  ohi <- nInt32s 100
  toPtr arr ((), ohi)
  b   <- isFilledWithEvens32 ohi 100
  assertEqual "Not equal" 1 b

testBlockCopyFromArrayInt64 :: IO ()
testBlockCopyFromArrayInt64 = do
  let n = 73
  let (arr :: Vector Int64) = fromList (Z:.n) [2 * P.fromIntegral x | x <- [0..n-1]]
  ohi <- nInt64s (P.fromIntegral n)
  toPtr arr ((), ohi)
  b   <- isFilledWithEvens64 ohi (P.fromIntegral n)
  assertEqual "Not equal" 1 b

foreign import ccall "one_to_ten" oneToTen :: IO (Ptr Int32)
foreign import ccall "ten_to_one" tenToOne :: IO (Ptr Double)
foreign import ccall "n_int_16s" nInt16s :: CInt -> IO (Ptr Int16)
foreign import ccall "n_int_32s" nInt32s :: CInt -> IO (Ptr Int32)
foreign import ccall "n_int_64s" nInt64s :: CInt -> IO (Ptr Int64)
foreign import ccall "is_filled_with_evens_16" isFilledWithEvens16 :: Ptr Int16 -> CInt -> IO CInt
foreign import ccall "is_filled_with_evens_32" isFilledWithEvens32 :: Ptr Int32 -> CInt -> IO CInt
foreign import ccall "is_filled_with_evens_64" isFilledWithEvens64 :: Ptr Int64 -> CInt -> IO CInt
foreign import ccall memcpy :: Ptr a -> Ptr b -> Int -> IO ()