Skip to content

Instantly share code, notes, and snippets.

@adithyaov
Last active August 18, 2022 15:01
Show Gist options
  • Save adithyaov/1dab38f209bd12a3dc216266a3b46b25 to your computer and use it in GitHub Desktop.
Save adithyaov/1dab38f209bd12a3dc216266a3b46b25 to your computer and use it in GitHub Desktop.
Test for checking the properties of GHC byte array alignment
import Data.Foldable (forM_)
import Data.Word(Word8)
import Foreign.Storable (Storable(..))
import GHC.Ptr (Ptr (..))
import GHC.Base (addr2Int#, int2Word#)
import Streamly.Internal.Data.Unboxed
( MutableByteArray(..)
, Unbox(..)
, Unboxed
, castContents
)
newtype TestAlignmentType = TestAlignmentType Word8
testAlignmentTypeAlignment :: Int
testAlignmentTypeAlignment = 64
instance Storable TestAlignmentType where
sizeOf _ = 1
alignment _ = testAlignmentTypeAlignment
peek = undefined
poke = undefined
instance Unbox TestAlignmentType where
box marr i = TestAlignmentType <$> box (castContents marr) i
unbox marr i (TestAlignmentType a) = unbox (castContents marr) i a
-- If this test passes, the following can be considered true:
-- 1. Alignment affects the entire chunk of the array and not every element.
-- 2. Alignemnt only matters in allocation. It is transparent, thereafter.
testAlignment :: IO ()
testAlignment = do
let n = 5
lst = [0 .. (n - 1)]
lstTA = TestAlignmentType . fromIntegral <$> lst
arr <- S.fold (Fold.foldlM' MA.snoc (MA.newArray n)) (S.fromList lstTA)
MA.asPtrUnsafe arr
$ \(Ptr a) ->
case fromIntegral (W# (int2Word# (addr2Int# a)))
`rem` testAlignmentTypeAlignment of
0 -> return ()
_ -> expectationFailure "Incorrect initial alignment."
let mW8Arr = MA.cast arr
case mW8Arr of
Nothing -> expectationFailure "Couldn't cast."
Just w8Arr -> MA.toList w8Arr `shouldReturn` (intToW8 <$> lst)
where
intToW8 :: Int -> Word8
intToW8 = fromIntegral
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment