{-# LANGUAGE DataKinds #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE TypeFamilies #-} {-# OPTIONS_GHC -O2 #-} import Data.Primitive.Compact import GHC.Compact import GHC.Prim import Data.Word import Data.Primitive.Array import Data.Primitive.PrimArray import Data.Primitive.ByteArray import Data.Primitive.PrimRef import Data.Primitive import Data.Functor.Identity import Data.Int import Control.Monad main :: IO () main = do putStrLn "Running compact-mutable tests" putStrLn "Trying normal compact functions as sanity check" _ <- newArray 13 (44 :: Int) >>= unsafeFreezeArray >>= compact _ <- newArray 11 (42 :: Int) >>= (\m -> freezeArray m 0 5) >>= compact nums <- newPrimArray 15 :: IO (MutablePrimArray RealWorld Int64) writePrimArray nums 0 58 nums2 <- fmap getCompact $ compact nums nums2Alias <- fmap getCompact $ compact nums2 writePrimArray nums2Alias 0 57 originalVal <- readPrimArray nums 0 copyVal <- readPrimArray nums2 0 aliasVal <- readPrimArray nums2Alias 0 when (originalVal /= 58) $ fail "original value wrong" when (copyVal /= 58) $ fail "copy value wrong" when (aliasVal /= 57) $ fail "alias value wrong" withToken $ \token -> do -- putStrLn "creating array" -- _ <- newCompactArray token 5 -- putStrLn "creating mutable array" -- _ <- newCompactArray token 5 -- putStrLn "creating array of arrays" -- c1 <- newCompactArray token 12 -- c2 <- newCompactArray token 5 -- writeCompactArray c1 0 (Yes c2) -- unsafeInsertCompactArray 4 2 (Yes c2) c1 -- writeCompactArray c1 1 No -- x <- readCompactArray c1 1 -- case x of -- No -> return () -- Yes _ -> fail "did not get expected value" -- copyCompactMutableArray c1 0 c1 4 3 -- c3 <- newCompactArray token 16 -- _ <- compactAddGeneral token (Identity c1) -- _ <- compactAddGeneral token (Identity c3) -- putStrLn "creating PrimRef" p1 <- Ref <$> newPrimRef (12 :: Word16) p2 <- compactAddGeneral token p1 -- p9 <- compactAddGeneral token (Thing (12 :: Word32)) -- -- !p3 <- compactAddGeneral token p2 -- _ <- newCompactArray token 3 putStrLn "attempting large loop" arr <- newCompactArray token 10000000 let go !n = if n < 10000000 then do !p3 <- compactAddGeneral token (Thing n) writeCompactArray arr n p3 go (n + 1) else return () go 0 -- printCompactArrayAddrs arr let goRead !n = if n < 10000000 then do Thing val <- readCompactArray arr n -- val <- readPrimRef r if val == n then return () else fail "found value not equal to n" goRead (n + 1) else return () goRead 0 putStrLn "finished large loop" putStrLn "aliasing behavior" a1 <- newCompactArray token 10 writeCompactArray a1 0 (Thing (79 :: Int)) a2 <- compactAddGeneral token a1 a3 <- compactAddGeneral token a2 writeCompactArray a3 0 (Thing (74 :: Int)) Thing n <- readCompactArray a1 0 when (n /= 74) $ fail "wrong value of n" putStrLn "finished aliasing behavior" putStrLn "testing contractible array" k1 <- newContractedArray token 2 k5 <- newContractedArray token 3 writeContractedArray k1 0 (Foo 55 k1) writeContractedArray k1 1 (Foo 12 k5) writeContractedArray k5 0 (Foo 33 k5) writeContractedArray k5 1 (Foo 42 k1) Foo n k2 <- readContractedArray k1 0 Foo m k3 <- readContractedArray k2 0 Foo _ k6 <- readContractedArray k5 0 Foo _ k7 <- readContractedArray k5 1 Foo _ _ <- readContractedArray k6 0 Foo _ _ <- readContractedArray k7 1 unsafeInsertContractedArray 2 1 (Foo 124 k1) k5 Foo _ k8 <- readContractedArray k5 2 Foo _ _ <- readContractedArray k8 1 Foo _ k9 <- readContractedArray k5 1 Foo _ _ <- readContractedArray k9 1 if n == 55 then return () else fail "n should be 55" if m == 55 then return () else fail "m should be 55" putStrLn "successful contractible array" return () -- Note: making types like this to put in a compact array is not -- typically safe. Do not do it unless you understand how the compact -- heap works. data Thing a (c :: Heap) = Thing !a data MaybeArray (c :: Heap) = No | Yes (CompactMutableArray RealWorld MaybeArray c) data Ref (c :: Heap) = Ref !(PrimRef RealWorld Word16) data Foo s c = Foo {-# UNPACK #-} !Int {-# UNPACK #-} !(ContractedMutableArray s (Foo s) c) instance Contractible (Foo s) where unsafeSizeOfContractedElement _ = sizeOf (undefined :: Int) * 2 unsafeWriteContractedArray (ContractedMutableArray marr) ix (Foo n (ContractedMutableArray (MutableByteArray nodes))) = do let machIx = ix * 2 writeByteArray marr (machIx + 0) n writeByteArray marr (machIx + 1) (unsafeUnliftedToAddr nodes) unsafeReadContractedArray (ContractedMutableArray marr) ix = do let machIx = ix * 2 a <- readByteArray marr (machIx + 0) f <- readByteArray marr (machIx + 1) return (Foo a (ContractedMutableArray (MutableByteArray (unsafeUnliftedFromAddr f))))