carray 0.1.2 → 0.1.3
raw patch · 2 files changed
+66/−39 lines, 2 filesdep +sybdep ~basePVP ok
version bump matches the API change (PVP)
Dependencies added: syb
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Data.Array.CArray.Base: offsetShapeFromThenTo :: [Int] -> [Int] -> [Int] -> [Int] -> [Int]
+ Data.Array.CArray.Base: offsetShapeFromTo :: [Int] -> [Int] -> [Int] -> [Int]
+ Data.Array.CArray.Base: offsetShapeFromTo' :: ([[Int]] -> [[Int]]) -> [Int] -> [Int] -> [Int] -> [Int]
Files
- Data/Array/CArray/Base.hs +55/−38
- carray.cabal +11/−1
Data/Array/CArray/Base.hs view
@@ -1,6 +1,12 @@-{-# OPTIONS_GHC -frewrite-rules #-} {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, MagicHash, FlexibleInstances, FlexibleContexts, UnboxedTuples, DeriveDataTypeable, CPP #-}+#ifdef __GLASGOW_HASKELL__+#if __GLASGOW_HASKELL__ < 610+{-# OPTIONS_GHC -frewrite-rules #-}+#else+{-# OPTIONS_GHC -fenable-rewrite-rules #-}+#endif+#endif ----------------------------------------------------------------------------- -- | -- Module : Data.Array.CArray.Base@@ -46,7 +52,7 @@ import Foreign.ForeignPtr import Foreign.Ptr import Foreign.Marshal.Alloc-import Foreign.Marshal.Array (copyArray,peekArray,pokeArray)+import Foreign.Marshal.Array (copyArray) import Data.Word (Word8,Word) import Data.Generics (Data(..), Typeable(..))@@ -66,14 +72,14 @@ instance Storable e => MArray IOCArray e IO where getBounds (IOCArray l u _ _) = return (l,u) - getNumElements (IOCArray l u n _) = return n+ getNumElements (IOCArray _ _ n _) = return n - newArray (l,u) init = do- fp <- mallocForeignPtrArrayAligned size+ newArray (l,u) e0 = do+ fp <- mallocForeignPtrArrayAligned n withForeignPtr fp $ \a ->- sequence_ [pokeElemOff a i init | i <- [0..size-1]]- return (IOCArray l u size fp)- where size = rangeSize (l,u)+ sequence_ [pokeElemOff a i e0 | i <- [0 .. n - 1]]+ return (IOCArray l u n fp)+ where n = rangeSize (l,u) unsafeNewArray_ (l,u) = do let n = rangeSize (l,u)@@ -127,9 +133,9 @@ -- | /O(1)/ Turn a CArray into a ByteString. Unsafe because it uses -- 'castForeignPtr' and thus is not platform independent. unsafeCArrayToByteString :: (Storable e) => CArray i e -> S.ByteString-unsafeCArrayToByteString (CArray _ _ l fp) = go undefined l fp- where go :: (Storable e) => e -> Int -> ForeignPtr e -> S.ByteString- go dummy l fp = S.fromForeignPtr (castForeignPtr fp) 0 (l * sizeOf dummy)+unsafeCArrayToByteString (CArray _ _ l fp) = go undefined fp+ where go :: (Storable e) => e -> ForeignPtr e -> S.ByteString+ go dummy fp' = S.fromForeignPtr (castForeignPtr fp') 0 (l * sizeOf dummy) -- | /O(1)/ Turn a ByteString into a CArray. Unsafe because it uses -- 'castForeignPtr' and thus is not platform independent. Returns 'Nothing' if@@ -138,11 +144,10 @@ -- CArray (as specified by the Storable instance). unsafeByteStringToCArray :: (Ix i, Storable e, IArray CArray e) => (i,i) -> S.ByteString -> Maybe (CArray i e)-unsafeByteStringToCArray (l,u) bs = go undefined (l,u) bs- where go :: (Ix i, Storable e, IArray CArray e)- => e -> (i,i) -> S.ByteString -> Maybe (CArray i e)- go dummy (l,u) bs | safe = Just (CArray l u n fp)- | otherwise = Nothing+unsafeByteStringToCArray lu bs = go undefined lu+ where go :: (Ix i, Storable e, IArray CArray e) => e -> (i,i) -> Maybe (CArray i e)+ go dummy (l,u) | safe = Just (CArray l u n fp)+ | otherwise = Nothing where n = rangeSize (l,u) ((ForeignPtr addr contents), off, len) = S.toForeignPtr bs p@(Ptr addr') = Ptr addr `plusPtr` off@@ -150,7 +155,7 @@ safe = sizeOf dummy * n <= len && p == p `alignPtr` alignment dummy copy :: (Ix i, Storable e) => CArray i e -> IO (CArray i e)-copy ain@(CArray l u n fp) =+copy ain@(CArray l u n _) = createCArray (l,u) $ \op -> withCArray ain $ \ip -> copyArray op ip n@@ -201,17 +206,17 @@ {-# NOINLINE unsafeAccum #-} unsafeAccum f arr ies = unsafePerformIO $ unsafeAccumCArray f arr ies {-# NOINLINE unsafeAccumArray #-}- unsafeAccumArray f init lu ies = unsafePerformIO $ unsafeAccumArrayCArray f init lu ies+ unsafeAccumArray f e0 lu ies = unsafePerformIO $ unsafeAccumArrayCArray f e0 lu ies -- | Hackish way to get the zero element for a Storable type. {-# NOINLINE zeroElem #-} zeroElem :: Storable a => a -> a zeroElem u = unsafePerformIO $ do- allocaBytes size $ \p -> do- sequence_ [pokeByteOff p off (0 :: Word8) | off <- [0 .. (size - 1)] ]+ allocaBytes n $ \p -> do+ sequence_ [pokeByteOff p off (0 :: Word8) | off <- [0 .. n - 1] ] peek (castPtr p)- where size = sizeOf u+ where n = sizeOf u {-# INLINE unsafeArrayCArray #-} unsafeArrayCArray :: (MArray IOCArray e IO, Storable e, Ix i)@@ -245,8 +250,8 @@ unsafeAccumArrayCArray :: (MArray IOCArray e IO, Storable e, Ix i) => (e -> e' -> e) -> e -> (i,i) -> [(Int, e')] -> IO (CArray i e)-unsafeAccumArrayCArray f init lu ies = do- marr <- newArray lu init+unsafeAccumArrayCArray f e0 lu ies = do+ marr <- newArray lu e0 sequence_ [do old <- unsafeRead marr i unsafeWrite marr i (f old new)@@ -298,14 +303,14 @@ -- | O(1) reshape an array. The number of elements in the new shape must not -- exceed the number in the old shape. The elements are in C-style ordering. reshape :: (Ix i, Ix j) => (j,j) -> CArray i e -> CArray j e-reshape (l',u') (CArray l u n fp) | n' > n = error "reshape: new size too large"- |otherwise = CArray l' u' n' fp+reshape (l',u') (CArray _ _ n fp) | n' > n = error "reshape: new size too large"+ | otherwise = CArray l' u' n' fp where n' = rangeSize (l', u') -- | O(1) make a rank 1 array from an arbitrary shape. -- It has the property that 'reshape (0, size a - 1) a == flatten a'. flatten :: Ix i => CArray i e -> CArray Int e-flatten (CArray l u n fp) = CArray 0 (n - 1) n fp+flatten (CArray _ _ n fp) = CArray 0 (n - 1) n fp -- | Determine the rank of an array. rank :: (Shapable i, Ix i, IArray a e) => a i e -> Int@@ -370,10 +375,10 @@ sliceStrideWithP :: (Ix i, Shapable i, Ix i', IArray a e, IArray a' e') => (i',i') -> (i,i,i) -> (e -> e') -> a i e -> a' i' e' sliceStrideWithP lu (start,next,end) f arr- | all (inRange (bounds arr)) [start,next,end] = listArray lu elems+ | all (inRange (bounds arr)) [start,next,end] = listArray lu es | otherwise = error "sliceStrideWith: out of bounds" where is = offsetShapeFromThenTo (shape arr) (index' start) (index' next) (index' end)- elems = map (f . (unsafeAt arr)) is+ es = map (f . (unsafeAt arr)) is index' = indexes arr -- | Less polymorphic version.@@ -395,10 +400,10 @@ sliceWithP :: (Ix i, Shapable i, Ix i', IArray a e, IArray a' e') => (i',i') -> (i,i) -> (e -> e') -> a i e -> a' i' e' sliceWithP lu (start,end) f arr- | all (inRange (bounds arr)) [start,end] = listArray lu elems+ | all (inRange (bounds arr)) [start,end] = listArray lu es | otherwise = error "sliceWith: out of bounds" where is = offsetShapeFromTo (shape arr) (index' start) (index' end)- elems = map (f . (unsafeAt arr)) is+ es = map (f . (unsafeAt arr)) is index' = indexes arr -- | Less polymorphic version.@@ -432,21 +437,24 @@ indexes :: (Ix i, Shapable i, IArray a e) => a i e -> i -> [Int] indexes a i = map pred $ (sShape . fst . bounds) a i +offsetShapeFromThenTo :: [Int] -> [Int] -> [Int] -> [Int] -> [Int] offsetShapeFromThenTo s a b c = foldr (liftA2 (+)) [0] (ilists stride a b c)- where ilists = zipWith4 (\s a b c -> map (*s) $ enumFromThenTo a b c)+ where ilists = zipWith4 (\s' a' b' c' -> map (*s') $ enumFromThenTo a' b' c') stride = shapeToStride s +offsetShapeFromTo :: [Int] -> [Int] -> [Int] -> [Int] offsetShapeFromTo = offsetShapeFromTo' id +offsetShapeFromTo' :: ([[Int]] -> [[Int]]) -> [Int] -> [Int] -> [Int] -> [Int] offsetShapeFromTo' f s a b = foldr (liftA2 (+)) [0] (f $ ilists stride a b)- where ilists = zipWith3 (\s a b -> map (*s) $ enumFromTo a b)+ where ilists = zipWith3 (\s' a' b' -> map (*s') $ enumFromTo a' b') stride = shapeToStride s offsets :: (Ix a, Shapable a) => (a, a) -> a -> [Int] offsets lu i = reverse . osets (index lu i) . reverse . scanl1 (*) . uncurry sShape $ lu where osets 0 [] = []- osets i (b:bs) = r : osets d bs- where (d,r) = i `divMod` b+ osets i' (b:bs) = r : osets d bs+ where (d,r) = i' `divMod` b osets _ _ = error "osets" ----------------------------------------- @@ -457,7 +465,7 @@ -- | 2-norm on the array taken as a vector (Frobenius norm for matrices) norm2 :: (Ix i, Floating e', Abs e e', IArray a e) => a i e -> e'-norm2 a = sqrt $ foldl' (\z e -> z + abs_ e ^ 2) 0 (elems a)+norm2 a = sqrt $ foldl' (\z e -> z + abs_ e ^ (2 :: Int)) 0 (elems a) -- | Sup norm on the array taken as a vector normSup :: (Ix i, Num e', Ord e', Abs e e', IArray a e) => a i e -> e'@@ -512,23 +520,27 @@ sRank _ = 1 sShape a a' = [rangeSize (a,a')] sBounds [a] = (0,a-1)+ sBounds _ = error "sBounds expected list length 1" instance Shapable (Int,Int) where sRank _ = 2 sShape (a,b) (a',b') = [rangeSize (a,a'), rangeSize (b,b')] sBounds [a,b] = ((0,0),(a-1,b-1))+ sBounds _ = error "sBounds expected list length 2" instance Shapable (Int,Int,Int) where sRank _ = 3 sShape (a,b,c) (a',b',c') = [rangeSize (a,a'), rangeSize (b,b'), rangeSize (c,c')] sBounds [a,b,c] = ((0,0,0),(a-1,b-1,c-1))+ sBounds _ = error "sBounds expected list length 3" instance Shapable (Int,Int,Int,Int) where sRank _ = 4 sShape (a,b,c,d) (a',b',c',d') = [rangeSize (a,a'), rangeSize (b,b'), rangeSize (c,c'), rangeSize (d,d')] sBounds [a,b,c,d] = ((0,0,0,0),(a-1,b-1,c-1,d-1))+ sBounds _ = error "sBounds expected list length 4" instance Shapable (Int,Int,Int,Int,Int) where sRank _ = 5@@ -536,6 +548,7 @@ [rangeSize (a,a'), rangeSize (b,b'), rangeSize (c,c'), rangeSize (d,d') , rangeSize (e,e')] sBounds [a,b,c,d,e] = ((0,0,0,0,0),(a-1,b-1,c-1,d-1,e-1))+ sBounds _ = error "sBounds expected list length 5" instance Shapable (Int,Int,Int,Int,Int,Int) where sRank _ = 6@@ -543,6 +556,7 @@ [rangeSize (a,a'), rangeSize (b,b'), rangeSize (c,c'), rangeSize (d,d') , rangeSize (e,e'), rangeSize (f,f')] sBounds [a,b,c,d,e,f] = ((0,0,0,0,0,0),(a-1,b-1,c-1,d-1,e-1,f-1))+ sBounds _ = error "sBounds expected list length 6" instance Shapable (Int,Int,Int,Int,Int,Int,Int) where sRank _ = 7@@ -550,6 +564,7 @@ [rangeSize (a,a'), rangeSize (b,b'), rangeSize (c,c'), rangeSize (d,d') , rangeSize (e,e'), rangeSize (f,f'), rangeSize (g,g')] sBounds [a,b,c,d,e,f,g] = ((0,0,0,0,0,0,0),(a-1,b-1,c-1,d-1,e-1,f-1,g-1))+ sBounds _ = error "sBounds expected list length 7" instance Shapable (Int,Int,Int,Int,Int,Int,Int,Int) where sRank _ = 8@@ -557,6 +572,7 @@ [rangeSize (a,a'), rangeSize (b,b'), rangeSize (c,c'), rangeSize (d,d') , rangeSize (e,e'), rangeSize (f,f'), rangeSize (g,g'), rangeSize (h,h')] sBounds [a,b,c,d,e,f,g,h] = ((0,0,0,0,0,0,0,0),(a-1,b-1,c-1,d-1,e-1,f-1,g-1,h-1))+ sBounds _ = error "sBounds expected list length 8" instance Shapable (Int,Int,Int,Int,Int,Int,Int,Int,Int) where sRank _ = 9@@ -566,6 +582,7 @@ , rangeSize (i,i')] sBounds [a,b,c,d,e,f,g,h,i] = ((0,0,0,0,0,0,0,0,0) ,(a-1,b-1,c-1,d-1,e-1,f-1,g-1,h-1,i-1))+ sBounds _ = error "sBounds expected list length 9" -- | Hack so that norms have a sensible type.@@ -613,10 +630,10 @@ -- | Allocate an array which is 16-byte aligned. Essential for SIMD instructions. mallocForeignPtrArrayAligned :: Storable a => Int -> IO (ForeignPtr a)-mallocForeignPtrArrayAligned n = doMalloc undefined n+mallocForeignPtrArrayAligned n = doMalloc undefined where- doMalloc :: Storable b => b -> Int -> IO (ForeignPtr b)- doMalloc dummy size = mallocForeignPtrBytesAligned (size * sizeOf dummy)+ doMalloc :: Storable b => b -> IO (ForeignPtr b)+ doMalloc dummy = mallocForeignPtrBytesAligned (n * sizeOf dummy) -- | Allocate memory which is 16-byte aligned. This is essential for SIMD -- instructions. We know that mallocPlainForeignPtrBytes will give word-aligned
carray.cabal view
@@ -1,5 +1,5 @@ name: carray-version: 0.1.2+version: 0.1.3 synopsis: A C-compatible array library. description: A C-compatible array library.@@ -18,7 +18,11 @@ build-type: Simple flag splitBase+ description: array was in base < 3 flag bytestringInBase+ description: bytestring was included in base for 2.0 and 2.1+flag base4+ description: syb was split from base >= 4 library if flag(bytestringInBase)@@ -31,6 +35,12 @@ else build-depends: base < 3, binary + if flag(base4)+ build-depends: base >= 4, syb >= 0.1+ else+ build-depends: base < 4+ exposed-modules: Data.Array.CArray Data.Array.IOCArray Data.Array.CArray.Base+ ghc-options: -Wall