#include "fusion-phases.h"
module Data.Array.Parallel.Unlifted.Sequential.Flat.UArr (
UA, UArr, MUArr,
lengthU, indexU, sliceU, unitsU, zipU, unzipU, fstU, sndU,
newU, newDynU, newDynResU,
lengthMU, newMU, readMU, writeMU, copyMU, unsafeFreezeMU, unsafeFreezeAllMU,
hasAtomicWriteMU, atomicWriteMU,
UIO(..)
) where
import Control.Monad (liftM, liftM2)
import GHC.Word (Word8)
import Data.Array.Parallel.Base
import Data.Array.Parallel.Arr (
BUArr, MBUArr, UAE,
lengthBU, indexBU, sliceBU, hGetBU, hPutBU,
lengthMBU, newMBU, readMBU, writeMBU, copyMBU, unsafeFreezeMBU)
import System.IO
infixl 9 `indexU`, `readMU`
class HS e => UA e where
data UArr e
data MUArr e :: * -> *
lengthU :: UArr e -> Int
indexU :: UArr e -> Int -> e
sliceU :: UArr e -> Int -> Int -> UArr e
lengthMU :: MUArr e s -> Int
newMU :: Int -> ST s (MUArr e s)
readMU :: MUArr e s -> Int -> ST s e
writeMU :: MUArr e s -> Int -> e -> ST s ()
hasAtomicWriteMU :: e -> Bool
atomicWriteMU :: MUArr e s -> Int -> e -> ST s ()
copyMU :: MUArr e s -> Int -> UArr e -> ST s ()
unsafeFreezeMU :: MUArr e s -> Int -> ST s (UArr e)
hasAtomicWriteMU _ = False
atomicWriteMU _ _ _ = error "atomicWriteMU: not supported"
instance HS e => HS (UArr e)
instance HS e => HS (MUArr e s)
class UAE e => UPrim e where
mkUAPrim :: BUArr e -> UArr e
unUAPrim :: UArr e -> BUArr e
mkMUAPrim :: MBUArr s e -> MUArr e s
unMUAPrim :: MUArr e s -> MBUArr s e
unsafeFreezeAllMU :: UA e => MUArr e s -> ST s (UArr e)
unsafeFreezeAllMU marr = unsafeFreezeMU marr (lengthMU marr)
newU :: UA e => Int -> (forall s. MUArr e s -> ST s ()) -> UArr e
newU n init = newDynU n (\ma -> init ma >> return n)
newDynU :: UA e => Int -> (forall s. MUArr e s -> ST s Int) -> UArr e
newDynU n init =
runST (do
ma <- newMU n
n' <- init ma
unsafeFreezeMU ma n'
)
newDynResU :: UA e
=> Int -> (forall s. MUArr e s -> ST s (Int :*: r)) -> UArr e :*: r
newDynResU n init =
runST (do
ma <- newMU n
n' :*: r <- init ma
arr <- unsafeFreezeMU ma n'
return (arr :*: r)
)
unitsU :: Int -> UArr ()
unitsU = UAUnit
zipU :: (UA a, UA b) => UArr a -> UArr b -> UArr (a :*: b)
zipU = UAProd
unzipU :: (UA a, UA b) => UArr (a :*: b) -> (UArr a :*: UArr b)
unzipU (UAProd l r) = (l :*: r)
fstU :: (UA a, UA b) => UArr (a :*: b) -> UArr a
fstU (UAProd l r) = l
sndU :: (UA a, UA b) => UArr (a :*: b) -> UArr b
sndU (UAProd l r) = r
instance UA () where
newtype UArr () = UAUnit Int
newtype MUArr () s = MUAUnit Int
lengthU (UAUnit n) = n
indexU (UAUnit _) _ = ()
sliceU (UAUnit _) _ n = UAUnit n
lengthMU (MUAUnit n) = n
newMU n = return $ MUAUnit n
readMU (MUAUnit _) _ = return ()
writeMU (MUAUnit _) _ _ = return ()
copyMU (MUAUnit _) _ (UAUnit _) = return ()
unsafeFreezeMU (MUAUnit _) n = return $ UAUnit n
hasAtomicWriteMU _ = True
atomicWriteMU = writeMU
instance (UA a, UA b) => UA (a :*: b) where
data UArr (a :*: b) = UAProd !(UArr a) !(UArr b)
data MUArr (a :*: b) s = MUAProd !(MUArr a s) !(MUArr b s)
lengthU (UAProd l r) = checkEq "lengthU" "lengths of zipped arrays differ" (lengthU l) (lengthU r)
(lengthU l)
indexU (UAProd l r) i = indexU l i :*: indexU r i
sliceU (UAProd l r) i n = UAProd (sliceU l i n) (sliceU r i n)
lengthMU (MUAProd l r) = lengthMU l
newMU n =
do
a <- newMU n
b <- newMU n
return $ MUAProd a b
readMU (MUAProd a b) i = liftM2 (:*:) (a `readMU` i) (b `readMU` i)
writeMU (MUAProd a b) i (x :*: y) =
do
writeMU a i x
writeMU b i y
copyMU (MUAProd ma mb) i (UAProd a b) =
do
copyMU ma i a
copyMU mb i b
unsafeFreezeMU (MUAProd a b) n =
do
a' <- unsafeFreezeMU a n
b' <- unsafeFreezeMU b n
return $ UAProd a' b'
primLengthU :: UPrim e => UArr e -> Int
primLengthU = lengthBU . unUAPrim
primIndexU :: UPrim e => UArr e -> Int -> e
primIndexU = indexBU . unUAPrim
primSliceU :: UPrim e => UArr e -> Int -> Int -> UArr e
primSliceU arr i = mkUAPrim . sliceBU (unUAPrim arr) i
primLengthMU :: UPrim e => MUArr e s -> Int
primLengthMU = lengthMBU . unMUAPrim
primNewMU :: UPrim e => Int -> ST s (MUArr e s)
primNewMU = liftM mkMUAPrim . newMBU
primReadMU :: UPrim e => MUArr e s -> Int -> ST s e
primReadMU = readMBU . unMUAPrim
primWriteMU :: UPrim e => MUArr e s -> Int -> e -> ST s ()
primWriteMU = writeMBU . unMUAPrim
primCopyMU :: UPrim e => MUArr e s -> Int -> UArr e -> ST s ()
primCopyMU ma i = copyMBU (unMUAPrim ma) i . unUAPrim
primUnsafeFreezeMU :: UPrim e => MUArr e s -> Int -> ST s (UArr e)
primUnsafeFreezeMU ma = liftM mkUAPrim . unsafeFreezeMBU (unMUAPrim ma)
instance UPrim Bool where
mkUAPrim = UABool
unUAPrim (UABool arr) = arr
mkMUAPrim = MUABool
unMUAPrim (MUABool arr) = arr
instance UA Bool where
newtype UArr Bool = UABool (BUArr Bool)
newtype MUArr Bool s = MUABool (MBUArr s Bool)
lengthU = primLengthU
indexU = primIndexU
sliceU = primSliceU
lengthMU = primLengthMU
newMU = primNewMU
readMU = primReadMU
writeMU = primWriteMU
copyMU = primCopyMU
unsafeFreezeMU = primUnsafeFreezeMU
instance UPrim Char where
mkUAPrim = UAChar
unUAPrim (UAChar arr) = arr
mkMUAPrim = MUAChar
unMUAPrim (MUAChar arr) = arr
instance UA Char where
newtype UArr Char = UAChar (BUArr Char)
newtype MUArr Char s = MUAChar (MBUArr s Char)
lengthU = primLengthU
indexU = primIndexU
sliceU = primSliceU
lengthMU = primLengthMU
newMU = primNewMU
readMU = primReadMU
writeMU = primWriteMU
copyMU = primCopyMU
unsafeFreezeMU = primUnsafeFreezeMU
instance UPrim Int where
mkUAPrim = UAInt
unUAPrim (UAInt arr) = arr
mkMUAPrim = MUAInt
unMUAPrim (MUAInt arr) = arr
instance UA Int where
newtype UArr Int = UAInt (BUArr Int)
newtype MUArr Int s = MUAInt (MBUArr s Int)
lengthU = primLengthU
indexU = primIndexU
sliceU = primSliceU
lengthMU = primLengthMU
newMU = primNewMU
readMU = primReadMU
writeMU = primWriteMU
copyMU = primCopyMU
unsafeFreezeMU = primUnsafeFreezeMU
hasAtomicWriteMU _ = True
atomicWriteMU = primWriteMU
instance UPrim Word8 where
mkUAPrim = UAWord8
unUAPrim (UAWord8 arr) = arr
mkMUAPrim = MUAWord8
unMUAPrim (MUAWord8 arr) = arr
instance UA Word8 where
newtype UArr Word8 = UAWord8 (BUArr Word8)
newtype MUArr Word8 s = MUAWord8 (MBUArr s Word8)
lengthU = primLengthU
indexU = primIndexU
sliceU = primSliceU
lengthMU = primLengthMU
newMU = primNewMU
readMU = primReadMU
writeMU = primWriteMU
copyMU = primCopyMU
unsafeFreezeMU = primUnsafeFreezeMU
hasAtomicWriteMU _ = True
atomicWriteMU = primWriteMU
instance UPrim Float where
mkUAPrim = UAFloat
unUAPrim (UAFloat arr) = arr
mkMUAPrim = MUAFloat
unMUAPrim (MUAFloat arr) = arr
instance UA Float where
newtype UArr Float = UAFloat (BUArr Float)
newtype MUArr Float s = MUAFloat (MBUArr s Float)
lengthU = primLengthU
indexU = primIndexU
sliceU = primSliceU
lengthMU = primLengthMU
newMU = primNewMU
readMU = primReadMU
writeMU = primWriteMU
copyMU = primCopyMU
unsafeFreezeMU = primUnsafeFreezeMU
instance UPrim Double where
mkUAPrim = UADouble
unUAPrim (UADouble arr) = arr
mkMUAPrim = MUADouble
unMUAPrim (MUADouble arr) = arr
instance UA Double where
newtype UArr Double = UADouble (BUArr Double)
newtype MUArr Double s = MUADouble (MBUArr s Double)
lengthU = primLengthU
indexU = primIndexU
sliceU = primSliceU
lengthMU = primLengthMU
newMU = primNewMU
readMU = primReadMU
writeMU = primWriteMU
copyMU = primCopyMU
unsafeFreezeMU = primUnsafeFreezeMU
class UA a => UIO a where
hPutU :: Handle -> UArr a -> IO ()
hGetU :: Handle -> IO (UArr a)
primPutU :: UPrim a => Handle -> UArr a -> IO ()
primPutU h = hPutBU h . unUAPrim
primGetU :: UPrim a => Handle -> IO (UArr a)
primGetU = liftM mkUAPrim . hGetBU
instance UIO Int where
hPutU = primPutU
hGetU = primGetU
instance UIO Double where
hPutU = primPutU
hGetU = primGetU
instance (UIO a, UIO b) => UIO (a :*: b) where
hPutU h (UAProd xs ys) = do hPutU h xs
hPutU h ys
hGetU h = do xs <- hGetU h
ys <- hGetU h
return (UAProd xs ys)