massiv 0.1.6.1 → 0.2.0.0
raw patch · 29 files changed
+397/−339 lines, 29 filesdep +unsupported-ghc-versionPVP ok
version bump matches the API change (PVP)
Dependencies added: unsupported-ghc-version
API changes (from Hackage documentation)
- Data.Massiv.Array.Mutable: data family MArray s r ix e :: *;
- Data.Massiv.Array.Mutable: forM :: (Monad m, Source r ix e, Mutable r' ix e') => r' -> Array r ix e -> (e -> m e') -> m (Array r' ix e')
- Data.Massiv.Array.Mutable: generateLinearM :: (Monad m, Mutable r ix e) => Comp -> ix -> (Int -> m e) -> m (Array r ix e)
- Data.Massiv.Array.Mutable: generateM :: (Monad m, Mutable r ix e) => Comp -> ix -> (ix -> m e) -> m (Array r ix e)
- Data.Massiv.Array.Mutable: iforM :: (Monad m, Source r ix e, Mutable r' ix e') => r' -> Array r ix e -> (ix -> e -> m e') -> m (Array r' ix e')
- Data.Massiv.Array.Mutable: imapM :: (Monad m, Source r ix e, Mutable r' ix e') => r' -> (ix -> e -> m e') -> Array r ix e -> m (Array r' ix e')
- Data.Massiv.Array.Mutable: mapM :: (Monad m, Source r ix e, Mutable r' ix e') => r' -> (e -> m e') -> Array r ix e -> m (Array r' ix e')
- Data.Massiv.Array.Mutable: sequenceM :: (Monad m, Source r ix (m e), Mutable r' ix e) => r' -> Array r ix (m e) -> m (Array r' ix e)
- Data.Massiv.Array.Mutable: }
- Data.Massiv.Array.Unsafe: forStencilUnsafe :: (Source r ix e, Manifest r ix e) => Array r ix e -> ix -> ix -> ((ix -> Maybe e) -> a) -> Array DW ix a
- Data.Massiv.Core.Index: [:>] :: {-# UNPACK #-} !Int -> !(Ix (n - 1)) -> IxN n
- Data.Massiv.Core.Index: rank :: Index ix => ix -> Dim
+ Data.Massiv.Array: (:.) :: {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> Ix2
+ Data.Massiv.Array: (:>) :: {-# UNPACK #-} !Int -> !(Ix (n - 1)) -> IxN
+ Data.Massiv.Array: Continue :: Border e
+ Data.Massiv.Array: D :: D
+ Data.Massiv.Array: DI :: DI
+ Data.Massiv.Array: DW :: DW
+ Data.Massiv.Array: Dim :: Int -> Dim
+ Data.Massiv.Array: Edge :: Border e
+ Data.Massiv.Array: Fill :: e -> Border e
+ Data.Massiv.Array: Ix0 :: Ix0
+ Data.Massiv.Array: L :: L
+ Data.Massiv.Array: ParOn :: [Int] -> Comp
+ Data.Massiv.Array: Reflect :: Border e
+ Data.Massiv.Array: Seq :: Comp
+ Data.Massiv.Array: Wrap :: Border e
+ Data.Massiv.Array: class (Typeable r, Index ix) => Construct r ix e
+ Data.Massiv.Array: class (Eq ix, Ord ix, Show ix, NFData ix) => Index ix where {
+ Data.Massiv.Array: class Size r ix e => InnerSlice r ix e
+ Data.Massiv.Array: class Size r ix e => Load r ix e
+ Data.Massiv.Array: class Source r ix e => Manifest r ix e
+ Data.Massiv.Array: class Manifest r ix e => Mutable r ix e
+ Data.Massiv.Array: class Nested r ix e
+ Data.Massiv.Array: class OuterSlice r ix e
+ Data.Massiv.Array: class Construct r ix e => Ragged r ix e
+ Data.Massiv.Array: class Construct r ix e => Size r ix e
+ Data.Massiv.Array: class Size r ix e => Slice r ix e
+ Data.Massiv.Array: class Size r ix e => Source r ix e
+ Data.Massiv.Array: cons :: Ragged r ix e => Elt r ix e -> Array r ix e -> Array r ix e
+ Data.Massiv.Array: consDim :: Index ix => Int -> Lower ix -> ix
+ Data.Massiv.Array: data Border e
+ Data.Massiv.Array: data Comp
+ Data.Massiv.Array: data D
+ Data.Massiv.Array: data DI
+ Data.Massiv.Array: data DW
+ Data.Massiv.Array: data Ix0
+ Data.Massiv.Array: data Ix2
+ Data.Massiv.Array: data IxN (n :: Nat)
+ Data.Massiv.Array: data L
+ Data.Massiv.Array: data LN
+ Data.Massiv.Array: delay :: Source r ix e => Array r ix e -> Array D ix e
+ Data.Massiv.Array: dimensions :: Index ix => ix -> Dim
+ Data.Massiv.Array: dropDim :: Index ix => ix -> Dim -> Maybe (Lower ix)
+ Data.Massiv.Array: edgeSize :: Ragged r ix e => Array r ix e -> ix
+ Data.Massiv.Array: empty :: Ragged r ix e => Comp -> Array r ix e
+ Data.Massiv.Array: errorIx :: (Show ix, Show ix') => String -> ix -> ix' -> a
+ Data.Massiv.Array: errorSizeMismatch :: (Show ix, Show ix') => String -> ix -> ix' -> a
+ Data.Massiv.Array: flatten :: Ragged r ix e => Array r ix e -> Array r Ix1 e
+ Data.Massiv.Array: fromIx2 :: Ix2 -> Ix2T
+ Data.Massiv.Array: fromIx3 :: Ix3 -> Ix3T
+ Data.Massiv.Array: fromIx4 :: Ix4 -> Ix4T
+ Data.Massiv.Array: fromIx5 :: Ix5 -> Ix5T
+ Data.Massiv.Array: fromLinearIndex :: (Index ix, Index (Lower ix)) => ix -> Int -> ix
+ Data.Massiv.Array: fromLinearIndexAcc :: (Index ix, Index (Lower ix)) => ix -> Int -> (Int, ix)
+ Data.Massiv.Array: fromNested :: Nested r ix e => NestedStruct r ix e -> Array r ix e
+ Data.Massiv.Array: getIndex :: Index ix => ix -> Dim -> Maybe Int
+ Data.Massiv.Array: handleBorderIndex :: Index ix => Border e -> ix -> (ix -> e) -> ix -> e
+ Data.Massiv.Array: headDim :: Index ix => ix -> Int
+ Data.Massiv.Array: initDim :: Index ix => ix -> Lower ix
+ Data.Massiv.Array: isNonEmpty :: Index ix => ix -> Bool
+ Data.Massiv.Array: isNull :: Ragged r ix e => Array r ix e -> Bool
+ Data.Massiv.Array: isSafeIndex :: (Index ix, Index (Lower ix)) => ix -> ix -> Bool
+ Data.Massiv.Array: isSafeSize :: Index ix => ix -> Bool
+ Data.Massiv.Array: iter :: Index ix => ix -> ix -> ix -> (Int -> Int -> Bool) -> a -> (ix -> a -> a) -> a
+ Data.Massiv.Array: iterLinearM :: (Index ix, Monad m) => ix -> Int -> Int -> Int -> (Int -> Int -> Bool) -> a -> (Int -> ix -> a -> m a) -> m a
+ Data.Massiv.Array: iterLinearM_ :: (Index ix, Monad m) => ix -> Int -> Int -> Int -> (Int -> Int -> Bool) -> (Int -> ix -> m ()) -> m ()
+ Data.Massiv.Array: iterM :: (Index ix, Index (Lower ix), Monad m) => ix -> ix -> ix -> (Int -> Int -> Bool) -> a -> (ix -> a -> m a) -> m a
+ Data.Massiv.Array: iterM_ :: (Index ix, Index (Lower ix), Monad m) => ix -> ix -> ix -> (Int -> Int -> Bool) -> (ix -> m a) -> m ()
+ Data.Massiv.Array: lastDim :: Index ix => ix -> Int
+ Data.Massiv.Array: liftIndex :: Index ix => (Int -> Int) -> ix -> ix
+ Data.Massiv.Array: liftIndex2 :: Index ix => (Int -> Int -> Int) -> ix -> ix -> ix
+ Data.Massiv.Array: loadP :: Load r ix e => [Int] -> Array r ix e -> (Int -> IO e) -> (Int -> e -> IO ()) -> IO ()
+ Data.Massiv.Array: loadRagged :: Ragged r ix e => (IO () -> IO ()) -> (Int -> e -> IO a) -> Int -> Int -> Lower ix -> Array r ix e -> IO ()
+ Data.Massiv.Array: loadS :: (Load r ix e, Monad m) => Array r ix e -> (Int -> m e) -> (Int -> e -> m ()) -> m ()
+ Data.Massiv.Array: loop :: Int -> (Int -> Bool) -> (Int -> Int) -> a -> (Int -> a -> a) -> a
+ Data.Massiv.Array: loopDeepM :: Monad m => Int -> (Int -> Bool) -> (Int -> Int) -> a -> (Int -> a -> m a) -> m a
+ Data.Massiv.Array: loopM :: Monad m => Int -> (Int -> Bool) -> (Int -> Int) -> a -> (Int -> a -> m a) -> m a
+ Data.Massiv.Array: loopM_ :: Monad m => Int -> (Int -> Bool) -> (Int -> Int) -> (Int -> m a) -> m ()
+ Data.Massiv.Array: makeWindowedArray :: Source r ix e => Array r ix e -> ix -> ix -> (ix -> e) -> Array DW ix e
+ Data.Massiv.Array: newtype Dim
+ Data.Massiv.Array: outerLength :: (OuterSlice r ix e, Size r ix e) => Array r ix e -> Int
+ Data.Massiv.Array: pureIndex :: Index ix => Int -> ix
+ Data.Massiv.Array: raggedFormat :: Ragged r ix e => (e -> String) -> String -> Array r ix e -> String
+ Data.Massiv.Array: repairIndex :: (Index ix, Index (Lower ix)) => ix -> ix -> (Int -> Int -> Int) -> (Int -> Int -> Int) -> ix
+ Data.Massiv.Array: setIndex :: Index ix => ix -> Dim -> Int -> Maybe ix
+ Data.Massiv.Array: snocDim :: Index ix => Lower ix -> Int -> ix
+ Data.Massiv.Array: tailDim :: Index ix => ix -> Lower ix
+ Data.Massiv.Array: toInterleaved :: Source r ix e => Array r ix e -> Array DI ix e
+ Data.Massiv.Array: toIx2 :: Ix2T -> Ix2
+ Data.Massiv.Array: toIx3 :: Ix3T -> Ix3
+ Data.Massiv.Array: toIx4 :: Ix4T -> Ix4
+ Data.Massiv.Array: toIx5 :: Ix5T -> Ix5
+ Data.Massiv.Array: toLinearIndex :: (Index ix, Index (Lower ix)) => ix -> ix -> Int
+ Data.Massiv.Array: toLinearIndexAcc :: (Index ix, Index (Lower ix)) => Int -> ix -> ix -> Int
+ Data.Massiv.Array: toNested :: Nested r ix e => Array r ix e -> NestedStruct r ix e
+ Data.Massiv.Array: totalElem :: Index ix => ix -> Int
+ Data.Massiv.Array: type Ix1 = Int
+ Data.Massiv.Array: type Ix1T = Int
+ Data.Massiv.Array: type Ix2T = (Int, Int)
+ Data.Massiv.Array: type Ix3 = IxN 3
+ Data.Massiv.Array: type Ix3T = (Int, Int, Int)
+ Data.Massiv.Array: type Ix4 = IxN 4
+ Data.Massiv.Array: type Ix4T = (Int, Int, Int, Int)
+ Data.Massiv.Array: type Ix5 = IxN 5
+ Data.Massiv.Array: type Ix5T = (Int, Int, Int, Int, Int)
+ Data.Massiv.Array: type family Dimensions ix :: Nat;
+ Data.Massiv.Array: uncons :: Ragged r ix e => Array r ix e -> Maybe (Elt r ix e, Array r ix e)
+ Data.Massiv.Array: unconsDim :: Index ix => ix -> (Int, Lower ix)
+ Data.Massiv.Array: unsnocDim :: Index ix => ix -> (Lower ix, Int)
+ Data.Massiv.Array: zeroIndex :: Index ix => ix
+ Data.Massiv.Array: }
+ Data.Massiv.Array.Delayed: DI :: DI
+ Data.Massiv.Array.Delayed: DW :: DW
+ Data.Massiv.Array.Delayed: unsafeBackpermuteDW :: Index ix => (ix -> ix) -> (ix -> ix) -> ix -> Array DW ix a -> Array DW ix a
+ Data.Massiv.Array.Stencil.Unsafe: forStencilUnsafe :: (Source r ix e, Manifest r ix e) => Array r ix e -> ix -> ix -> ((ix -> Maybe e) -> a) -> Array DW ix a
+ Data.Massiv.Core.Index: (:>) :: {-# UNPACK #-} !Int -> !(Ix (n - 1)) -> IxN
+ Data.Massiv.Core.Index: dimensions :: Index ix => ix -> Dim
- Data.Massiv.Array: convertAs :: (Mutable r' ix e, Mutable r ix e, Typeable ix, Typeable e) => r -> Array r' ix e -> Array r ix e
+ Data.Massiv.Array: convertAs :: (Manifest r' ix e, Mutable r ix e) => r -> Array r' ix e -> Array r ix e
- Data.Massiv.Array: convertProxy :: (Mutable r' ix e, Mutable r ix e, Typeable ix, Typeable e) => proxy r -> Array r' ix e -> Array r ix e
+ Data.Massiv.Array: convertProxy :: (Manifest r' ix e, Mutable r ix e) => proxy r -> Array r' ix e -> Array r ix e
- Data.Massiv.Array.Mutable: class Manifest r ix e => Mutable r ix e where {
+ Data.Massiv.Array.Mutable: class Manifest r ix e => Mutable r ix e
- Data.Massiv.Array.Mutable: data RealWorld :: *
+ Data.Massiv.Array.Mutable: data RealWorld
- Data.Massiv.Array.Stencil: makeConvolutionStencil :: (Index ix, Num e) => Border e -> ix -> ix -> ((ix -> Value e -> Value e -> Value e) -> Value e -> Value e) -> Stencil ix e e
+ Data.Massiv.Array.Stencil: makeConvolutionStencil :: (Index ix, Num e) => ix -> ix -> ((ix -> Value e -> Value e -> Value e) -> Value e -> Value e) -> Stencil ix e e
- Data.Massiv.Array.Stencil: makeConvolutionStencilFromKernel :: (Manifest r ix e, Num e) => Border e -> Array r ix e -> Stencil ix e e
+ Data.Massiv.Array.Stencil: makeConvolutionStencilFromKernel :: (Manifest r ix e, Num e) => Array r ix e -> Stencil ix e e
- Data.Massiv.Array.Stencil: makeCorrelationStencil :: (Index ix, Num e) => Border e -> ix -> ix -> ((ix -> Value e -> Value e -> Value e) -> Value e -> Value e) -> Stencil ix e e
+ Data.Massiv.Array.Stencil: makeCorrelationStencil :: (Index ix, Num e) => ix -> ix -> ((ix -> Value e -> Value e -> Value e) -> Value e -> Value e) -> Stencil ix e e
- Data.Massiv.Array.Stencil: makeCorrelationStencilFromKernel :: (Manifest r ix e, Num e) => Border e -> Array r ix e -> Stencil ix e e
+ Data.Massiv.Array.Stencil: makeCorrelationStencilFromKernel :: (Manifest r ix e, Num e) => Array r ix e -> Stencil ix e e
- Data.Massiv.Array.Stencil: makeStencil :: (Index ix, Default e) => Border e -> ix -> ix -> ((ix -> Value e) -> Value a) -> Stencil ix e a
+ Data.Massiv.Array.Stencil: makeStencil :: (Index ix, Default e) => ix -> ix -> ((ix -> Value e) -> Value a) -> Stencil ix e a
- Data.Massiv.Array.Stencil: mapStencil :: (Source r ix e, Manifest r ix e) => Stencil ix e a -> Array r ix e -> Array DW ix a
+ Data.Massiv.Array.Stencil: mapStencil :: (Source r ix e, Manifest r ix e) => Border e -> Stencil ix e a -> Array r ix e -> Array DW ix a
- Data.Massiv.Core.Index: iter :: Index ix => ix -> ix -> Int -> (Int -> Int -> Bool) -> a -> (ix -> a -> a) -> a
+ Data.Massiv.Core.Index: iter :: Index ix => ix -> ix -> ix -> (Int -> Int -> Bool) -> a -> (ix -> a -> a) -> a
- Data.Massiv.Core.Index: iterM :: (Index ix, Index (Lower ix), Monad m) => ix -> ix -> Int -> (Int -> Int -> Bool) -> a -> (ix -> a -> m a) -> m a
+ Data.Massiv.Core.Index: iterM :: (Index ix, Index (Lower ix), Monad m) => ix -> ix -> ix -> (Int -> Int -> Bool) -> a -> (ix -> a -> m a) -> m a
- Data.Massiv.Core.Index: iterM_ :: (Index ix, Index (Lower ix), Monad m) => ix -> ix -> Int -> (Int -> Int -> Bool) -> (ix -> m a) -> m ()
+ Data.Massiv.Core.Index: iterM_ :: (Index ix, Index (Lower ix), Monad m) => ix -> ix -> ix -> (Int -> Int -> Bool) -> (ix -> m a) -> m ()
- Data.Massiv.Core.Index: type family Rank ix :: Nat;
+ Data.Massiv.Core.Index: type family Dimensions ix :: Nat;
Files
- massiv.cabal +16/−10
- src/Data/Massiv/Array.hs +18/−10
- src/Data/Massiv/Array/Delayed.hs +3/−2
- src/Data/Massiv/Array/Delayed/Interleaved.hs +2/−2
- src/Data/Massiv/Array/Delayed/Internal.hs +2/−2
- src/Data/Massiv/Array/Delayed/Windowed.hs +77/−31
- src/Data/Massiv/Array/Manifest/BoxedStrict.hs +1/−1
- src/Data/Massiv/Array/Manifest/Internal.hs +11/−11
- src/Data/Massiv/Array/Manifest/List.hs +4/−4
- src/Data/Massiv/Array/Mutable.hs +12/−6
- src/Data/Massiv/Array/Ops/Fold/Internal.hs +2/−2
- src/Data/Massiv/Array/Ops/Map.hs +1/−1
- src/Data/Massiv/Array/Ops/Slice.hs +4/−4
- src/Data/Massiv/Array/Ops/Transform.hs +7/−7
- src/Data/Massiv/Array/Stencil.hs +14/−11
- src/Data/Massiv/Array/Stencil/Convolution.hs +12/−16
- src/Data/Massiv/Array/Stencil/Internal.hs +7/−40
- src/Data/Massiv/Array/Stencil/Unsafe.hs +54/−0
- src/Data/Massiv/Array/Unsafe.hs +1/−4
- src/Data/Massiv/Core/Common.hs +1/−1
- src/Data/Massiv/Core/Index/Class.hs +38/−36
- src/Data/Massiv/Core/Index/Ix.hs +27/−29
- src/Data/Massiv/Core/List.hs +17/−2
- src/Data/Massiv/Core/Scheduler.hs +1/−1
- tests/Data/Massiv/Array/MutableSpec.hs +0/−66
- tests/Data/Massiv/Array/Ops/SliceSpec.hs +1/−1
- tests/Data/Massiv/Array/StencilSpec.hs +48/−25
- tests/Data/Massiv/Core/IndexSpec.hs +14/−12
- tests/Spec.hs +2/−2
massiv.cabal view
@@ -1,5 +1,5 @@ name: massiv-version: 0.1.6.1+version: 0.2.0.0 synopsis: Massiv (Массив) is an Array Library. description: Multi-dimensional Arrays with fusion, stencils and parallel computation. homepage: https://github.com/lehins/massiv@@ -22,6 +22,7 @@ , Data.Massiv.Array.Mutable , Data.Massiv.Array.Numeric , Data.Massiv.Array.Stencil+ , Data.Massiv.Array.Stencil.Unsafe , Data.Massiv.Array.Unsafe , Data.Massiv.Core , Data.Massiv.Core.Scheduler@@ -60,18 +61,20 @@ if impl(ghc < 8.0) build-depends: semigroups+ if impl(ghc < 7.10)+ build-depends: unsupported-ghc-version > 1 && < 1 default-language: Haskell2010 ghc-options: -Wall -Test-Suite tests- Type: exitcode-stdio-1.0- HS-Source-Dirs: tests- Main-Is: Spec.hs- Other-Modules: Data.Massiv.Array.DelayedSpec+test-suite tests+ type: exitcode-stdio-1.0+ hs-source-dirs: tests+ main-is: Spec.hs+ other-modules: Data.Massiv.Array.DelayedSpec , Data.Massiv.Array.Manifest.VectorSpec- , Data.Massiv.Array.MutableSpec+ --, Data.Massiv.Array.MutableSpec , Data.Massiv.Array.Ops.ConstructSpec , Data.Massiv.Array.Ops.FoldSpec , Data.Massiv.Array.Ops.SliceSpec@@ -80,7 +83,7 @@ , Data.Massiv.CoreArbitrary , Data.Massiv.Core.IndexSpec , Data.Massiv.Core.SchedulerSpec- Build-Depends: base >= 4.8 && < 5+ build-depends: base >= 4.8 && < 5 , deepseq , data-default , safe-exceptions@@ -88,8 +91,11 @@ , hspec , QuickCheck , vector- Default-Language: Haskell2010- GHC-Options: -Wall -O2 -fno-warn-orphans -threaded -with-rtsopts=-N2+ if impl(ghc < 8.0)+ build-depends: semigroups++ default-language: Haskell2010+ ghc-options: -Wall -O2 -fno-warn-orphans -threaded -with-rtsopts=-N2 source-repository head type: git
src/Data/Massiv/Array.hs view
@@ -122,7 +122,7 @@ , module Data.Massiv.Array.Numeric ) where -import Data.Massiv.Array.Delayed+import Data.Massiv.Array.Delayed hiding (unsafeBackpermuteDW) import Data.Massiv.Array.Manifest import Data.Massiv.Array.Manifest.Internal import Data.Massiv.Array.Manifest.List@@ -134,16 +134,24 @@ import Data.Massiv.Array.Ops.Slice import Data.Massiv.Array.Ops.Transform import Data.Massiv.Array.Stencil-import Data.Massiv.Core hiding (elemsCount,- isEmpty)-import qualified Data.Massiv.Core as Core (elemsCount,- isEmpty)+-- Slightly convoluted re-export of this functions is done for better haddock.+import Data.Massiv.Core hiding (elemsCount, isEmpty)+import qualified Data.Massiv.Core as Core (elemsCount, isEmpty) import Data.Massiv.Core.Common-import Prelude as P hiding (all, and, any,- foldl, foldr, mapM,- mapM_, maximum,- minimum, or, product,- splitAt, sum)+import Prelude as P hiding ( all+ , and+ , any+ , foldl+ , foldr+ , mapM+ , mapM_+ , maximum+ , minimum+ , or+ , product+ , splitAt+ , sum+ ) {- $folding All folding is done in a row-major order.
src/Data/Massiv/Array/Delayed.hs view
@@ -12,10 +12,11 @@ module Data.Massiv.Array.Delayed ( D(..) , delay- , DI+ , DI(..) , toInterleaved- , DW+ , DW(..) , makeWindowedArray+ , unsafeBackpermuteDW ) where import Data.Massiv.Array.Delayed.Interleaved
src/Data/Massiv/Array/Delayed/Interleaved.hs view
@@ -13,7 +13,7 @@ -- Portability : non-portable -- module Data.Massiv.Array.Delayed.Interleaved- ( DI+ ( DI(..) , toInterleaved ) where @@ -24,7 +24,7 @@ -- | Delayed array that will be loaded in an interleaved fasion during parallel -- computation.-data DI+data DI = DI type instance EltRepr DI ix = DI
src/Data/Massiv/Array/Delayed/Internal.hs view
@@ -138,7 +138,7 @@ instance Index ix => Load D ix e where loadS (DArray _ sz f) _ unsafeWrite =- iterM_ zeroIndex sz 1 (<) $ \ !ix ->+ iterM_ zeroIndex sz (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (f ix) {-# INLINE loadS #-} loadP wIds (DArray _ sz f) _ unsafeWrite = do@@ -146,7 +146,7 @@ loopM_ 0 (< slackStart) (+ chunkLength) $ \ !start -> scheduleWork scheduler $ iterLinearM_ sz start (start + chunkLength) 1 (<) $ \ !k !ix -> do- unsafeWrite k $ f ix+ unsafeWrite k (f ix) scheduleWork scheduler $ iterLinearM_ sz slackStart totalLength 1 (<) $ \ !k !ix -> do unsafeWrite k (f ix)
src/Data/Massiv/Array/Delayed/Windowed.hs view
@@ -1,8 +1,8 @@-{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} -- |@@ -14,19 +14,25 @@ -- Portability : non-portable -- module Data.Massiv.Array.Delayed.Windowed- ( DW+ ( DW(..) , Array(..) , makeWindowedArray+ , unsafeBackpermuteDW ) where -import Control.Monad (when)+import Control.Monad (when) import Data.Massiv.Array.Delayed.Internal+import Data.Massiv.Array.Manifest.BoxedStrict+import Data.Massiv.Array.Manifest.Internal import Data.Massiv.Core import Data.Massiv.Core.Common+import Data.Massiv.Core.List (showArray) import Data.Massiv.Core.Scheduler+import Data.Proxy (Proxy (..))+import Data.Typeable (showsTypeRep, typeRep) -- | Delayed Windowed Array representation.-data DW+data DW = DW type instance EltRepr DW ix = D @@ -39,6 +45,12 @@ , wdWindowSize :: !ix , wdWindowUnsafeIndex :: ix -> e } ++instance {-# OVERLAPPING #-} (Show e, Ragged L ix e, Load DW ix e) =>+ Show (Array DW ix e) where+ show arr = showArray (showsTypeRep (typeRep (Proxy :: Proxy DW)) " ") (computeAs B arr)++ instance Index ix => Construct DW ix e where getComp = dComp . wdArray {-# INLINE getComp #-}@@ -107,28 +119,62 @@ {-# INLINE makeWindowedArray #-} +-- | Backpermute a windowed array. If index mappings aren't correct reading memory out of bounds is+-- very likely.+--+-- __Note__: windowStartIndex is mapped to the new windowStartIndex using the "old to new index"+-- map. This means that the order of the elements should be preserved, or performance will take a+-- major hit.+--+-- __Important__: This function is still experimental and can be removed in any future minor+-- release.+--+-- @since 0.2.0+unsafeBackpermuteDW ::+ Index ix+ => (ix -> ix) -- ^ map from old to new index+ -> (ix -> ix) -- ^ map from new to old index+ -> ix -- ^ Size of resulting array+ -> Array DW ix a+ -> Array DW ix a+unsafeBackpermuteDW toNewIndex toOldIndex sz DWArray {..} =+ DWArray+ { wdArray =+ DArray {dComp = dComp wdArray, dSize = sz, dUnsafeIndex = dUnsafeIndex wdArray . toOldIndex}+ , wdStencilSize = wdStencilSize+ , wdWindowStartIndex = newWindowStartIndex+ , wdWindowSize =+ liftIndex2+ (-)+ (toNewIndex (liftIndex2 (+) wdWindowStartIndex wdWindowSize))+ newWindowStartIndex+ , wdWindowUnsafeIndex = wdWindowUnsafeIndex . toOldIndex+ }+ where+ !newWindowStartIndex = toNewIndex wdWindowStartIndex+{-# INLINE unsafeBackpermuteDW #-} instance {-# OVERLAPPING #-} Load DW Ix1 e where loadS (DWArray (DArray _ sz indexB) _ it wk indexW) _ unsafeWrite = do- iterM_ 0 it 1 (<) $ \ !i -> unsafeWrite i (indexB i)- iterM_ it wk 1 (<) $ \ !i -> unsafeWrite i (indexW i)- iterM_ wk sz 1 (<) $ \ !i -> unsafeWrite i (indexB i)+ iterM_ 0 it (pureIndex 1) (<) $ \ !i -> unsafeWrite i (indexB i)+ iterM_ it wk (pureIndex 1) (<) $ \ !i -> unsafeWrite i (indexW i)+ iterM_ wk sz (pureIndex 1) (<) $ \ !i -> unsafeWrite i (indexB i) {-# INLINE loadS #-} loadP wIds (DWArray (DArray _ sz indexB) _ it wk indexW) _ unsafeWrite = do divideWork_ wIds wk $ \ !scheduler !chunkLength !totalLength !slackStart -> do scheduleWork scheduler $- iterM_ 0 it 1 (<) $ \ !ix ->+ iterM_ 0 it (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix) scheduleWork scheduler $- iterM_ wk sz 1 (<) $ \ !ix ->+ iterM_ wk sz (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix) loopM_ it (< (slackStart + it)) (+ chunkLength) $ \ !start -> scheduleWork scheduler $- iterM_ start (start + chunkLength) 1 (<) $ \ !k ->+ iterM_ start (start + chunkLength) (pureIndex 1) (<) $ \ !k -> unsafeWrite k $ indexW k scheduleWork scheduler $- iterM_ (slackStart + it) (totalLength + it) 1 (<) $ \ !k ->+ iterM_ (slackStart + it) (totalLength + it) (pureIndex 1) (<) $ \ !k -> unsafeWrite k (indexW k) {-# INLINE loadP #-} @@ -142,13 +188,13 @@ blockHeight = case mStencilSz of Just (i :. _) -> i _ -> 1- iterM_ (0 :. 0) (it :. n) 1 (<) $ \ !ix ->+ iterM_ (0 :. 0) (it :. n) (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix)- iterM_ (ib :. 0) (m :. n) 1 (<) $ \ !ix ->+ iterM_ (ib :. 0) (m :. n) (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix)- iterM_ (it :. 0) (ib :. jt) 1 (<) $ \ !ix ->+ iterM_ (it :. 0) (ib :. jt) (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix)- iterM_ (it :. jb) (ib :. n) 1 (<) $ \ !ix ->+ iterM_ (it :. jb) (ib :. n) (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix) unrollAndJam blockHeight (it :. ib) (jt :. jb) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexW ix)@@ -166,16 +212,16 @@ unsafeWrite (toLinearIndex sz ix) (indexW ix) {-# INLINE loadBlock #-} scheduleWork scheduler $- iterM_ (0 :. 0) (it :. n) 1 (<) $ \ !ix ->+ iterM_ (0 :. 0) (it :. n) (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix) scheduleWork scheduler $- iterM_ (ib :. 0) (m :. n) 1 (<) $ \ !ix ->+ iterM_ (ib :. 0) (m :. n) (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix) scheduleWork scheduler $- iterM_ (it :. 0) (ib :. jt) 1 (<) $ \ !ix ->+ iterM_ (it :. 0) (ib :. jt) (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix) scheduleWork scheduler $- iterM_ (it :. jb) (ib :. n) 1 (<) $ \ !ix ->+ iterM_ (it :. jb) (ib :. n) (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix) loopM_ 0 (< numWorkers scheduler) (+ 1) $ \ !wid -> do let !it' = wid * chunkHeight + it@@ -211,9 +257,9 @@ !pageElements = totalElem szL unsafeWriteLower i k val = unsafeWrite (k + pageElements * i) val {-# INLINE unsafeWriteLower #-}- iterM_ zeroIndex tix 1 (<) $ \ !ix ->+ iterM_ zeroIndex tix (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix)- iterM_ bix sz 1 (<) $ \ !ix ->+ iterM_ bix sz (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix) loopM_ t (< headDim bix) (+ 1) $ \ !i -> let !lowerArr =@@ -240,10 +286,10 @@ unsafeWriteLower i k = unsafeWrite (k + pageElements * i) {-# INLINE unsafeWriteLower #-} scheduleWork scheduler $- iterM_ zeroIndex tix 1 (<) $ \ !ix ->+ iterM_ zeroIndex tix (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix) scheduleWork scheduler $- iterM_ bix sz 1 (<) $ \ !ix ->+ iterM_ bix sz (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix) loopM_ t (< headDim bix) (+ 1) $ \ !i -> let !lowerArr =@@ -302,13 +348,13 @@ blockHeight = case mStencilSz of Just (i, _) -> i _ -> 1- iterM_ (0, 0) (it, n) 1 (<) $ \ !ix ->+ iterM_ (0, 0) (it, n) (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix)- iterM_ (ib, 0) (m, n) 1 (<) $ \ !ix ->+ iterM_ (ib, 0) (m, n) (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix)- iterM_ (it, 0) (ib, jt) 1 (<) $ \ !ix ->+ iterM_ (it, 0) (ib, jt) (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix)- iterM_ (it, jb) (ib, n) 1 (<) $ \ !ix ->+ iterM_ (it, jb) (ib, n) (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix) unrollAndJamT blockHeight (it, ib) (jt, jb) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexW ix)@@ -326,16 +372,16 @@ unsafeWrite (toLinearIndex sz ix) (indexW ix) {-# INLINE loadBlock #-} scheduleWork scheduler $- iterM_ (0, 0) (it, n) 1 (<) $ \ !ix ->+ iterM_ (0, 0) (it, n) (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix) scheduleWork scheduler $- iterM_ (ib, 0) (m, n) 1 (<) $ \ !ix ->+ iterM_ (ib, 0) (m, n) (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix) scheduleWork scheduler $- iterM_ (it, 0) (ib, jt) 1 (<) $ \ !ix ->+ iterM_ (it, 0) (ib, jt) (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix) scheduleWork scheduler $- iterM_ (it, jb) (ib, n) 1 (<) $ \ !ix ->+ iterM_ (it, jb) (ib, n) (pureIndex 1) (<) $ \ !ix -> unsafeWrite (toLinearIndex sz ix) (indexB ix) loopM_ 0 (< numWorkers scheduler) (+ 1) $ \ !wid -> do let !it' = wid * chunkHeight + it
src/Data/Massiv/Array/Manifest/BoxedStrict.hs view
@@ -28,7 +28,7 @@ import Data.Massiv.Array.Manifest.Internal import Data.Massiv.Array.Manifest.List as A import Data.Massiv.Array.Mutable-import Data.Massiv.Array.Ops.Fold+import Data.Massiv.Array.Ops.Fold.Internal import Data.Massiv.Core.Common import Data.Massiv.Core.List import qualified Data.Primitive.Array as A
src/Data/Massiv/Array/Manifest/Internal.hs view
@@ -38,21 +38,21 @@ , fromRaggedArray' ) where -import Control.Exception (try)-import Control.Monad (unless)-import Control.Monad.ST (RealWorld, runST)-import Data.Foldable (Foldable (..))+import Control.Exception (try)+import Control.Monad (unless)+import Control.Monad.ST (RealWorld, runST)+import Data.Foldable (Foldable (..)) import Data.Massiv.Array.Delayed.Internal-import Data.Massiv.Array.Ops.Fold as M+import Data.Massiv.Array.Ops.Fold.Internal as M import Data.Massiv.Array.Unsafe import Data.Massiv.Core.Common import Data.Massiv.Core.List import Data.Massiv.Core.Scheduler-import Data.Maybe (fromMaybe)+import Data.Maybe (fromMaybe) import Data.Typeable-import qualified Data.Vector as V-import GHC.Base (build)-import System.IO.Unsafe (unsafePerformIO)+import qualified Data.Vector as V+import GHC.Base (build)+import System.IO.Unsafe (unsafePerformIO) -- | General Manifest representation@@ -292,7 +292,7 @@ {-# INLINE convert #-} -- | Same as `convert`, but let's you supply resulting representation type as an argument.-convertAs :: (Mutable r' ix e, Mutable r ix e, Typeable ix, Typeable e)+convertAs :: (Manifest r' ix e, Mutable r ix e) => r -> Array r' ix e -> Array r ix e convertAs _ = convert {-# INLINE convertAs #-}@@ -303,7 +303,7 @@ -- -- @since 0.1.1 ---convertProxy :: (Mutable r' ix e, Mutable r ix e, Typeable ix, Typeable e)+convertProxy :: (Manifest r' ix e, Mutable r ix e) => proxy r -> Array r' ix e -> Array r ix e convertProxy _ = convert {-# INLINE convertProxy #-}
src/Data/Massiv/Array/Manifest/List.hs view
@@ -26,13 +26,13 @@ , toLists4 ) where -import Data.Massiv.Array.Delayed (D (..))+import Data.Massiv.Array.Delayed.Internal (D (..)) import Data.Massiv.Array.Manifest.Internal-import Data.Massiv.Array.Ops.Construct (makeArrayR)-import Data.Massiv.Array.Ops.Fold (foldrFB, foldrS)+import Data.Massiv.Array.Ops.Construct (makeArrayR)+import Data.Massiv.Array.Ops.Fold.Internal (foldrFB, foldrS) import Data.Massiv.Core.Common import Data.Massiv.Core.List-import GHC.Base (build)+import GHC.Base (build) -- | Convert a flat list into a vector fromList :: (Nested LN Ix1 e, Nested L Ix1 e, Ragged L Ix1 e, Mutable r Ix1 e)
src/Data/Massiv/Array/Mutable.hs view
@@ -35,13 +35,13 @@ -- * Generate (experimental) -- $generate- , generateM+ {-, generateM , generateLinearM , mapM , imapM , forM , iforM- , sequenceM+ , sequenceM -} ) where import Prelude hiding (mapM, read)@@ -51,7 +51,7 @@ import Data.Massiv.Array.Manifest.Internal import Data.Massiv.Array.Unsafe import Data.Massiv.Core.Common-import GHC.Base (Int (..))+--import GHC.Base (Int (..)) import GHC.Prim -- errorSizeMismatch fName sz1 sz2 =@@ -174,7 +174,7 @@ else ix1 {-# INLINE swap' #-} -+{- unsafeLinearFillM :: (Mutable r ix e, Monad m) => MArray RealWorld r ix e -> (Int -> m e) -> WorldState -> m WorldState unsafeLinearFillM ma f (State s_#) = go 0# s_#@@ -273,11 +273,17 @@ r' -> Array r ix (m e) -> m (Array r' ix e) sequenceM r = mapM r id {-# INLINE sequenceM #-}-+-} {- $generate -Functions in this sections can monadically generate manifest arrays using their associated mutable+Functions in this section has been removed until better times due to a known bug https://github.com/lehins/massiv/issues/24++-}++{-++Functions in this section can monadically generate manifest arrays using their associated mutable interface. Due to the sequential nature of monads generation is done also sequentially regardless of supplied computation strategy. All of functions here are very much experimental, so please <https://github.com/lehins/massiv/issues/new report an issue> if you see something not working
src/Data/Massiv/Array/Ops/Fold/Internal.hs view
@@ -86,7 +86,7 @@ -- | /O(n)/ - Monadic left fold with an index aware function. ifoldlM :: (Source r ix e, Monad m) => (a -> ix -> e -> m a) -> a -> Array r ix e -> m a ifoldlM f !acc !arr =- iterM zeroIndex (size arr) 1 (<) acc $ \ !ix !a -> f a ix (unsafeIndex arr ix)+ iterM zeroIndex (size arr) (pureIndex 1) (<) acc $ \ !ix !a -> f a ix (unsafeIndex arr ix) {-# INLINE ifoldlM #-} @@ -111,7 +111,7 @@ -- | /O(n)/ - Monadic right fold with an index aware function. ifoldrM :: (Source r ix e, Monad m) => (ix -> e -> a -> m a) -> a -> Array r ix e -> m a ifoldrM f !acc !arr =- iterM (liftIndex (subtract 1) (size arr)) zeroIndex (-1) (>=) acc $ \ !ix !acc0 ->+ iterM (liftIndex (subtract 1) (size arr)) zeroIndex (pureIndex (-1)) (>=) acc $ \ !ix !acc0 -> f ix (unsafeIndex arr ix) acc0 {-# INLINE ifoldrM #-}
src/Data/Massiv/Array/Ops/Map.hs view
@@ -128,7 +128,7 @@ -- 58 -- mapM_ :: (Source r ix a, Monad m) => (a -> m b) -> Array r ix a -> m ()-mapM_ f !arr = iterM_ zeroIndex (size arr) 1 (<) (f . unsafeIndex arr)+mapM_ f !arr = iterM_ zeroIndex (size arr) (pureIndex 1) (<) (f . unsafeIndex arr) {-# INLINE mapM_ #-}
src/Data/Massiv/Array/Ops/Slice.hs view
@@ -148,7 +148,7 @@ -- | /O(1)/ - Slices the array in any available dimension. Throws an error when -- index is out of bounds or dimensions is invalid. ----- prop> arr !> i == arr <!> (rank (size arr), i)+-- prop> arr !> i == arr <!> (dimensions (size arr), i) -- prop> arr <! i == arr <!> (1,i) -- (<!>) :: Slice r ix e => Array r ix e -> (Dim, Int) -> Elt r ix e@@ -156,11 +156,11 @@ case arr <!?> (dim, i) of Just res -> res Nothing ->- let arrRank = rank (size arr)- in if dim < 1 || dim > arrRank+ let arrDims = dimensions (size arr)+ in if dim < 1 || dim > arrDims then error $ "(<!>): Invalid dimension: " ++- show dim ++ " for Array of rank: " ++ show arrRank+ show dim ++ " for Array of dimensions: " ++ show arrDims else errorIx "(<!>)" (size arr) (dim, i) {-# INLINE (<!>) #-}
src/Data/Massiv/Array/Ops/Transform.hs view
@@ -162,10 +162,10 @@ where transInner !ix = fromMaybe (errorImpossible "transposeInner" ix) $ do- n <- getIndex ix (rank ix)- m <- getIndex ix (rank ix - 1)- ix' <- setIndex ix (rank ix) m- setIndex ix' (rank ix - 1) n+ n <- getIndex ix (dimensions ix)+ m <- getIndex ix (dimensions ix - 1)+ ix' <- setIndex ix (dimensions ix) m+ setIndex ix' (dimensions ix - 1) n {-# INLINE transInner #-} newVal = unsafeIndex arr . transInner {-# INLINE newVal #-}@@ -243,7 +243,7 @@ -- backpermute :: (Source r' ix' e, Index ix) => ix -- ^ Size of the result array- -> (ix -> ix') -- ^ A function that maps indices of old array into the source one.+ -> (ix -> ix') -- ^ A function that maps indices of the new array into the source one. -> Array r' ix' e -- ^ Source array. -> Array D ix e backpermute sz ixF !arr = makeArray (getComp arr) sz (evaluateAt arr . ixF)@@ -314,7 +314,7 @@ Just arr -> arr Nothing -> error $- if 0 < dim && dim <= rank (size arr1)+ if 0 < dim && dim <= dimensions (size arr1) then "append': Dimension mismatch: " ++ show (size arr1) ++ " and " ++ show (size arr2) else "append': Invalid dimension: " ++ show dim {-# INLINE append' #-}@@ -345,7 +345,7 @@ Nothing -> error $ "Data.Massiv.Array.splitAt': " ++- if 0 < dim && dim <= rank (size arr)+ if 0 < dim && dim <= dimensions (size arr) then "Index out of bounds: " ++ show i ++ " for dimension: " ++ show dim ++ " and array with size: " ++ show (size arr) else "Invalid dimension: " ++ show dim ++ " for array with size: " ++ show (size arr)
src/Data/Massiv/Array/Stencil.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RecordWildCards #-} -- | -- Module : Data.Massiv.Array.Stencil -- Copyright : (c) Alexey Kuleshevich 2018@@ -13,8 +14,8 @@ ( -- * Stencil Stencil , Value- , mapStencil , makeStencil+ , mapStencil -- * Convolution , module Data.Massiv.Array.Stencil.Convolution ) where@@ -30,9 +31,13 @@ -- | Map a constructed stencil over an array. Resulting array must be `compute`d in order to be -- useful.-mapStencil :: (Source r ix e, Manifest r ix e) =>- Stencil ix e a -> Array r ix e -> Array DW ix a-mapStencil (Stencil b sSz sCenter stencilF) !arr =+mapStencil ::+ (Source r ix e, Manifest r ix e)+ => Border e -- ^ Border resolution technique+ -> Stencil ix e a -- ^ Stencil to map over the array+ -> Array r ix e -- ^ Source array+ -> Array DW ix a+mapStencil b (Stencil sSz sCenter stencilF) !arr = DWArray (DArray (getComp arr) sz (unValue . stencilF (Value . borderIndex b arr))) (Just sSz)@@ -57,8 +62,8 @@ -- for each element in that array. /Note:/ Make sure to add @INLINE@ pragma, -- otherwise performance will be terrible. ----- > average3x3Stencil :: (Default a, Fractional a) => Border a -> Stencil Ix2 a a--- > average3x3Stencil b = makeStencil b (3 :. 3) (1 :. 1) $ \ get ->+-- > average3x3Stencil :: (Default a, Fractional a) => Stencil Ix2 a a+-- > average3x3Stencil = makeStencil (3 :. 3) (1 :. 1) $ \ get -> -- > ( get (-1 :. -1) + get (-1 :. 0) + get (-1 :. 1) + -- > get ( 0 :. -1) + get ( 0 :. 0) + get ( 0 :. 1) + -- > get ( 1 :. -1) + get ( 1 :. 0) + get ( 1 :. 1) ) / 9@@ -66,8 +71,7 @@ -- makeStencil :: (Index ix, Default e)- => Border e -- ^ Border resolution technique- -> ix -- ^ Size of the stencil+ => ix -- ^ Size of the stencil -> ix -- ^ Center of the stencil -> ((ix -> Value e) -> Value a) -- ^ Stencil function that receives a "get" function as it's argument that can@@ -77,13 +81,12 @@ -- cannot go outside the boundaries of the stencil, otherwise an error will be -- raised during stencil creation. -> Stencil ix e a-makeStencil b !sSz !sCenter relStencil =- validateStencil def $ Stencil b sSz sCenter stencil+makeStencil !sSz !sCenter relStencil =+ validateStencil def $ Stencil sSz sCenter stencil where stencil getVal !ix = (inline relStencil $ \ !ixD -> getVal (liftIndex2 (+) ix ixD)) {-# INLINE stencil #-} {-# INLINE makeStencil #-}-
src/Data/Massiv/Array/Stencil/Convolution.hs view
@@ -27,8 +27,8 @@ -- -- Here is how to create a 2D horizontal Sobel Stencil: ----- > sobelX :: Num e => Border e -> Stencil Ix2 e e--- > sobelX b = makeConvolutionStencil b (3 :. 3) (1 :. 1) $+-- > sobelX :: Num e => Stencil Ix2 e e+-- > sobelX = makeConvolutionStencil (3 :. 3) (1 :. 1) $ -- > \f -> f (-1 :. -1) 1 . f (-1 :. 1) (-1) . -- > f ( 0 :. -1) 2 . f ( 0 :. 1) (-2) . -- > f ( 1 :. -1) 1 . f ( 1 :. 1) (-1)@@ -36,13 +36,12 @@ -- makeConvolutionStencil :: (Index ix, Num e)- => Border e- -> ix+ => ix -> ix -> ((ix -> Value e -> Value e -> Value e) -> Value e -> Value e) -> Stencil ix e e-makeConvolutionStencil b !sSz !sCenter relStencil =- validateStencil 0 $ Stencil b sSz sCenter stencil+makeConvolutionStencil !sSz !sCenter relStencil =+ validateStencil 0 $ Stencil sSz sCenter stencil where stencil getVal !ix = ((inline relStencil $ \ !ixD !kVal !acc ->@@ -57,10 +56,9 @@ -- kernel at compile time. makeConvolutionStencilFromKernel :: (Manifest r ix e, Num e)- => Border e- -> Array r ix e+ => Array r ix e -> Stencil ix e e-makeConvolutionStencilFromKernel b kArr = Stencil b sz sCenter stencil+makeConvolutionStencilFromKernel kArr = Stencil sz sCenter stencil where !sz = size kArr !sCenter = (liftIndex (`div` 2) sz)@@ -76,13 +74,12 @@ -- | Make a <https://en.wikipedia.org/wiki/Cross-correlation cross-correlation> stencil. makeCorrelationStencil :: (Index ix, Num e)- => Border e- -> ix+ => ix -> ix -> ((ix -> Value e -> Value e -> Value e) -> Value e -> Value e) -> Stencil ix e e-makeCorrelationStencil b !sSz !sCenter relStencil =- validateStencil 0 $ Stencil b sSz sCenter stencil+makeCorrelationStencil !sSz !sCenter relStencil =+ validateStencil 0 $ Stencil sSz sCenter stencil where stencil getVal !ix = ((inline relStencil $ \ !ixD !kVal !acc ->@@ -97,10 +94,9 @@ -- kernel at compile time. makeCorrelationStencilFromKernel :: (Manifest r ix e, Num e)- => Border e- -> Array r ix e+ => Array r ix e -> Stencil ix e e-makeCorrelationStencilFromKernel b kArr = Stencil b sz sCenter stencil+makeCorrelationStencilFromKernel kArr = Stencil sz sCenter stencil where !sz = size kArr !sCenter = (liftIndex (`div` 2) sz)
src/Data/Massiv/Array/Stencil/Internal.hs view
@@ -19,9 +19,7 @@ import Control.DeepSeq import Data.Default.Class (Default (def)) import Data.Massiv.Array.Delayed.Internal-import Data.Massiv.Array.Delayed.Windowed import Data.Massiv.Core.Common-import GHC.Exts (inline) #if !MIN_VERSION_base(4,11,0) import Data.Semigroup #endif@@ -30,19 +28,18 @@ -- cell in order to compute a value for the cells in the new array. Use `Data.Array.makeStencil` and -- `Data.Array.makeConvolutionStencil` in order to create a stencil. data Stencil ix e a = Stencil- { stencilBorder :: Border e- , stencilSize :: !ix+ { stencilSize :: !ix , stencilCenter :: !ix , stencilFunc :: (ix -> Value e) -> ix -> Value a } instance (NFData e, Index ix) => NFData (Stencil ix e a) where- rnf (Stencil b sz ix f) = b `deepseq` sz `deepseq` ix `deepseq` f `seq` ()+ rnf (Stencil sz ix f) = sz `deepseq` ix `deepseq` f `seq` () -- | This is a simple wrapper for value of an array cell. It is used in order to improve safety of -- `Stencil` mapping. Using various class instances, such as `Num` and `Functor` for example, make -- it possible to manipulate the value, without having direct access to it.-newtype Value e = Value { unValue :: e } deriving (Show, Eq, Ord, Bounded)+newtype Value e = Value { unValue :: e } deriving (Show, Bounded) instance Functor Value where fmap f (Value e) = Value (f e)@@ -144,10 +141,10 @@ -- Stencil - both stencils are trusted, increasing the size will not affect the -- safety. instance (Default e, Index ix) => Applicative (Stencil ix e) where- pure a = Stencil Edge (pureIndex 1) zeroIndex (const (const (Value a)))+ pure a = Stencil (pureIndex 1) zeroIndex (const (const (Value a))) {-# INLINE pure #-}- (<*>) (Stencil _ sSz1 sC1 f1) (Stencil sB sSz2 sC2 f2) =- validateStencil def (Stencil sB newSz maxCenter stF)+ (<*>) (Stencil sSz1 sC1 f1) (Stencil sSz2 sC2 f2) =+ validateStencil def (Stencil newSz maxCenter stF) where stF gV !ix = Value ((unValue (f1 gV ix)) (unValue (f2 gV ix))) {-# INLINE stF #-}@@ -234,37 +231,7 @@ validateStencil :: Index ix => e -> Stencil ix e a -> Stencil ix e a-validateStencil d s@(Stencil _ sSz sCenter stencil) =+validateStencil d s@(Stencil sSz sCenter stencil) = let valArr = DArray Seq sSz (const d) in stencil (Value . safeStencilIndex valArr) sCenter `seq` s {-# INLINE validateStencil #-}----- | This is an unsafe version of the stencil computation. There are no bounds check further from--- the border, so if you make sure you don't go outside the size of the stencil, you will be safe,--- but this is not enforced.-forStencilUnsafe ::- (Source r ix e, Manifest r ix e)- => Array r ix e- -> ix -- ^ Size of the stencil- -> ix -- ^ Center of the stencil- -> ((ix -> Maybe e) -> a)- -- ^ Stencil function that receives a "get" function as it's argument that can- -- retrieve values of cells in the source array with respect to the center of- -- the stencil. Stencil function must return a value that will be assigned to- -- the cell in the result array. Offset supplied to the "get" function- -- cannot go outside the boundaries of the stencil, otherwise an error will be- -- raised during stencil creation.- -> Array DW ix a-forStencilUnsafe !arr !sSz !sCenter relStencil =- DWArray- (DArray (getComp arr) sz (stencil (index arr)))- (Just sSz)- sCenter- (liftIndex2 (-) sz (liftIndex2 (-) sSz (pureIndex 1)))- (stencil (Just . unsafeIndex arr))- where- stencil getVal !ix = (inline relStencil $ \ !ixD -> getVal (liftIndex2 (+) ix ixD))- {-# INLINE stencil #-}- !sz = size arr-{-# INLINE forStencilUnsafe #-}
+ src/Data/Massiv/Array/Stencil/Unsafe.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+-- |+-- Module : Data.Massiv.Array.Stencil.Unsafe+-- Copyright : (c) Alexey Kuleshevich 2018+-- License : BSD3+-- Maintainer : Alexey Kuleshevich <lehins@yandex.ru>+-- Stability : experimental+-- Portability : non-portable+--+module Data.Massiv.Array.Stencil.Unsafe+ ( -- * Stencil+ forStencilUnsafe+ ) where++import Data.Massiv.Core.Common+import Data.Massiv.Array.Delayed.Windowed+import GHC.Exts (inline)+++-- | This is an unsafe version of the stencil computation. There are no bounds check further from+-- the border, so if you make sure you don't go outside the size of the stencil, you will be safe,+-- but this is not enforced.+--+-- __/Note/__ - Still experimental and subject to change+--+-- @since 0.1.7+forStencilUnsafe ::+ (Source r ix e, Manifest r ix e)+ => Array r ix e+ -> ix -- ^ Size of the stencil+ -> ix -- ^ Center of the stencil+ -> ((ix -> Maybe e) -> a)+ -- ^ Stencil function that receives a "get" function as it's argument that can+ -- retrieve values of cells in the source array with respect to the center of+ -- the stencil. Stencil function must return a value that will be assigned to+ -- the cell in the result array. Offset supplied to the "get" function+ -- cannot go outside the boundaries of the stencil, otherwise an error will be+ -- raised during stencil creation.+ -> Array DW ix a+forStencilUnsafe !arr !sSz !sCenter relStencil =+ DWArray+ (DArray (getComp arr) sz (stencil (index arr)))+ (Just sSz)+ sCenter+ (liftIndex2 (-) sz (liftIndex2 (-) sSz (pureIndex 1)))+ (stencil (Just . unsafeIndex arr))+ where+ stencil getVal !ix = (inline relStencil $ \ !ixD -> getVal (liftIndex2 (+) ix ixD))+ {-# INLINE stencil #-}+ !sz = size arr+{-# INLINE forStencilUnsafe #-}
src/Data/Massiv/Array/Unsafe.hs view
@@ -3,7 +3,7 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} -- |--- Module : Data.Massiv.Array.Ops.Unsafe+-- Module : Data.Massiv.Array.Unsafe -- Copyright : (c) Alexey Kuleshevich 2018 -- License : BSD3 -- Maintainer : Alexey Kuleshevich <lehins@yandex.ru>@@ -39,14 +39,11 @@ , unsafeLinearRead , unsafeWrite , unsafeLinearWrite- -- * Stencil- , forStencilUnsafe ) where import Control.Monad.Primitive (PrimMonad (..)) import Control.Monad.ST (runST) import Data.Massiv.Array.Delayed.Internal (D)-import Data.Massiv.Array.Stencil.Internal import Data.Massiv.Core.Common import Data.Massiv.Core.Scheduler import System.IO.Unsafe (unsafePerformIO)
src/Data/Massiv/Core/Common.hs view
@@ -369,5 +369,5 @@ -- imapM_ :: (Source r ix a, Monad m) => (ix -> a -> m b) -> Array r ix a -> m () imapM_ f !arr =- iterM_ zeroIndex (size arr) 1 (<) $ \ !ix -> f ix (unsafeIndex arr ix)+ iterM_ zeroIndex (size arr) (pureIndex 1) (<) $ \ !ix -> f ix (unsafeIndex arr ix) {-# INLINE imapM_ #-}
src/Data/Massiv/Core/Index/Class.hs view
@@ -28,7 +28,7 @@ -- `Index` for it, and is included for completeness. data Ix0 = Ix0 deriving (Eq, Ord, Show) --- | 1-dimensional index. Synonym for `Int` and `Data.Massiv.Core.Index.Ix.Ix1`.+-- | 1-dimensional index. Synonym for `Int` and `Data.Massiv.Core.Index.Ix1`. type Ix1T = Int -- | 2-dimensional index as tuple of `Int`s.@@ -57,10 +57,10 @@ -- functions in this class will be useful to a regular user, unless general algorithms are being -- implemented that do span multiple dimensions. class (Eq ix, Ord ix, Show ix, NFData ix) => Index ix where- type Rank ix :: Nat+ type Dimensions ix :: Nat - -- | Rank of an array that has this index type, i.e. what is the dimensionality.- rank :: ix -> Dim+ -- | Dimensions of an array that has this index type, i.e. what is the dimensionality.+ dimensions :: ix -> Dim -- | Total number of elements in an array of this size. totalElem :: ix -> Int@@ -165,49 +165,51 @@ {-# INLINE [1] repairIndex #-} -- | Iterator for the index. Same as `iterM`, but pure.- iter :: ix -> ix -> Int -> (Int -> Int -> Bool) -> a -> (ix -> a -> a) -> a- iter sIx eIx inc cond acc f =- runIdentity $ iterM sIx eIx inc cond acc (\ix -> return . f ix)+ iter :: ix -> ix -> ix -> (Int -> Int -> Bool) -> a -> (ix -> a -> a) -> a+ iter sIx eIx incIx cond acc f =+ runIdentity $ iterM sIx eIx incIx cond acc (\ix -> return . f ix) {-# INLINE iter #-} -- | This function is what makes it possible to iterate over an array of any dimension. iterM :: Monad m => ix -- ^ Start index -> ix -- ^ End index- -> Int -- ^ Increment+ -> ix -- ^ Increment -> (Int -> Int -> Bool) -- ^ Continue iterating while predicate is True (eg. until end of row) -> a -- ^ Initial value for an accumulator -> (ix -> a -> m a) -- ^ Accumulator function -> m a default iterM :: (Index (Lower ix), Monad m)- => ix -> ix -> Int -> (Int -> Int -> Bool) -> a -> (ix -> a -> m a) -> m a- iterM !sIx !eIx !inc cond !acc f =- loopM k0 (`cond` k1) (+ inc) acc $ \ !i !acc0 ->- iterM sIxL eIxL inc cond acc0 $ \ !ix ->+ => ix -> ix -> ix -> (Int -> Int -> Bool) -> a -> (ix -> a -> m a) -> m a+ iterM !sIx !eIx !incIx cond !acc f =+ loopM s (`cond` e) (+ inc) acc $ \ !i !acc0 ->+ iterM sIxL eIxL incIxL cond acc0 $ \ !ix -> f (consDim i ix) where- !(k0, sIxL) = unconsDim sIx- !(k1, eIxL) = unconsDim eIx+ !(s, sIxL) = unconsDim sIx+ !(e, eIxL) = unconsDim eIx+ !(inc, incIxL) = unconsDim incIx {-# INLINE iterM #-} -- | Same as `iterM`, but don't bother with accumulator and return value.- iterM_ :: Monad m => ix -> ix -> Int -> (Int -> Int -> Bool) -> (ix -> m a) -> m ()+ iterM_ :: Monad m => ix -> ix -> ix -> (Int -> Int -> Bool) -> (ix -> m a) -> m () default iterM_ :: (Index (Lower ix), Monad m)- => ix -> ix -> Int -> (Int -> Int -> Bool) -> (ix -> m a) -> m ()- iterM_ !sIx !eIx !inc cond f =- loopM_ k0 (`cond` k1) (+ inc) $ \ !i ->- iterM_ sIxL eIxL inc cond $ \ !ix ->+ => ix -> ix -> ix -> (Int -> Int -> Bool) -> (ix -> m a) -> m ()+ iterM_ !sIx !eIx !incIx cond f =+ loopM_ s (`cond` e) (+ inc) $ \ !i ->+ iterM_ sIxL eIxL incIxL cond $ \ !ix -> f (consDim i ix) where- !(k0, sIxL) = unconsDim sIx- !(k1, eIxL) = unconsDim eIx+ !(s, sIxL) = unconsDim sIx+ !(e, eIxL) = unconsDim eIx+ !(inc, incIxL) = unconsDim incIx {-# INLINE iterM_ #-} instance Index Ix1T where- type Rank Ix1T = 1- rank _ = 1- {-# INLINE [1] rank #-}+ type Dimensions Ix1T = 1+ dimensions _ = 1+ {-# INLINE [1] dimensions #-} totalElem = id {-# INLINE [1] totalElem #-} isSafeIndex !k !i = 0 <= i && i < k@@ -257,9 +259,9 @@ instance Index Ix2T where- type Rank Ix2T = 2- rank _ = 2- {-# INLINE [1] rank #-}+ type Dimensions Ix2T = 2+ dimensions _ = 2+ {-# INLINE [1] dimensions #-} totalElem !(m, n) = m * n {-# INLINE [1] totalElem #-} toLinearIndex !(_, n) !(i, j) = n * i + j@@ -293,9 +295,9 @@ instance Index Ix3T where- type Rank Ix3T = 3- rank _ = 3- {-# INLINE [1] rank #-}+ type Dimensions Ix3T = 3+ dimensions _ = 3+ {-# INLINE [1] dimensions #-} totalElem !(m, n, o) = m * n * o {-# INLINE [1] totalElem #-} consDim i (j, k) = (i, j, k)@@ -328,9 +330,9 @@ instance Index Ix4T where- type Rank Ix4T = 4- rank _ = 4- {-# INLINE [1] rank #-}+ type Dimensions Ix4T = 4+ dimensions _ = 4+ {-# INLINE [1] dimensions #-} totalElem !(n1, n2, n3, n4) = n1 * n2 * n3 * n4 {-# INLINE [1] totalElem #-} consDim i1 (i2, i3, i4) = (i1, i2, i3, i4)@@ -366,9 +368,9 @@ instance Index Ix5T where- type Rank Ix5T = 5- rank _ = 5- {-# INLINE [1] rank #-}+ type Dimensions Ix5T = 5+ dimensions _ = 5+ {-# INLINE [1] dimensions #-} totalElem !(n1, n2, n3, n4, n5) = n1 * n2 * n3 * n4 * n5 {-# INLINE [1] totalElem #-} consDim i1 (i2, i3, i4, i5) = (i1, i2, i3, i4, i5)
src/Data/Massiv/Core/Index/Ix.hs view
@@ -3,7 +3,6 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE GADTs #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE ScopedTypeVariables #-}@@ -12,9 +11,9 @@ {-# LANGUAGE UndecidableInstances #-} #if __GLASGOW_HASKELL__ >= 800- {-# LANGUAGE TypeFamilyDependencies #-}-+#else+{-# LANGUAGE GADTs #-} #endif -- | -- Module : Data.Massiv.Core.Index.Ix@@ -27,13 +26,13 @@ module Data.Massiv.Core.Index.Ix where import Control.DeepSeq-import Control.Monad (liftM)+import Control.Monad (liftM) import Data.Massiv.Core.Index.Class-import Data.Monoid ((<>))+import Data.Monoid ((<>)) import Data.Proxy-import qualified Data.Vector.Generic as V-import qualified Data.Vector.Generic.Mutable as VM-import qualified Data.Vector.Unboxed as VU+import qualified Data.Vector.Generic as V+import qualified Data.Vector.Generic.Mutable as VM+import qualified Data.Vector.Unboxed as VU import GHC.TypeLits @@ -80,8 +79,7 @@ #if __GLASGOW_HASKELL__ >= 800 -- | n-dimensional index. Needs a base case, which is the `Ix2`.-data IxN (n :: Nat) where- (:>) :: {-# UNPACK #-} !Int -> !(Ix (n - 1)) -> IxN n+data IxN (n :: Nat) = (:>) {-# UNPACK #-} !Int !(Ix (n - 1)) -- | Defines n-dimensional index by relating a general `IxN` with few base cases. type family Ix (n :: Nat) = r | r -> n where@@ -93,7 +91,7 @@ #else data IxN (n :: Nat) where- (:>) :: Rank (Ix (n - 1)) ~ (n - 1) => {-# UNPACK #-} !Int -> !(Ix (n - 1)) -> IxN n+ (:>) :: Dimensions (Ix (n - 1)) ~ (n - 1) => {-# UNPACK #-} !Int -> !(Ix (n - 1)) -> IxN n type family Ix (n :: Nat) where Ix 0 = Ix0@@ -152,7 +150,7 @@ KnownNat n, Index (Ix (n - 1)), #if __GLASGOW_HASKELL__ < 800- Rank (Ix ((n - 1) - 1)) ~ ((n - 1) - 1),+ Dimensions (Ix ((n - 1) - 1)) ~ ((n - 1) - 1), #endif IxN (n - 1) ~ Ix (n - 1) ) => Num (IxN n) where@@ -189,7 +187,7 @@ KnownNat n, Index (Ix (n - 1)), #if __GLASGOW_HASKELL__ < 800- Rank (Ix ((n - 1) - 1)) ~ ((n - 1) - 1),+ Dimensions (Ix ((n - 1) - 1)) ~ ((n - 1) - 1), #endif IxN (n - 1) ~ Ix (n - 1) ) => Bounded (IxN n) where@@ -260,9 +258,9 @@ instance {-# OVERLAPPING #-} Index Ix2 where- type Rank Ix2 = 2- rank _ = 2- {-# INLINE [1] rank #-}+ type Dimensions Ix2 = 2+ dimensions _ = 2+ {-# INLINE [1] dimensions #-} totalElem (m :. n) = m * n {-# INLINE [1] totalElem #-} isSafeIndex (m :. n) (i :. j) = 0 <= i && 0 <= j && i < m && j < n@@ -304,9 +302,9 @@ instance {-# OVERLAPPING #-} Index (IxN 3) where- type Rank Ix3 = 3- rank _ = 3- {-# INLINE [1] rank #-}+ type Dimensions Ix3 = 3+ dimensions _ = 3+ {-# INLINE [1] dimensions #-} totalElem (m :> n :. o) = m * n * o {-# INLINE [1] totalElem #-} isSafeIndex (m :> n :. o) (i :> j :. k) =@@ -353,13 +351,13 @@ KnownNat n, Index (Ix (n - 1)), #if __GLASGOW_HASKELL__ < 800- Rank (Ix ((n - 1) - 1)) ~ ((n - 1) - 1),+ Dimensions (Ix ((n - 1) - 1)) ~ ((n - 1) - 1), #endif IxN (n - 1) ~ Ix (n - 1) ) => Index (IxN n) where- type Rank (IxN n) = n- rank _ = fromInteger $ natVal (Proxy :: Proxy n)- {-# INLINE [1] rank #-}+ type Dimensions (IxN n) = n+ dimensions _ = fromInteger $ natVal (Proxy :: Proxy n)+ {-# INLINE [1] dimensions #-} totalElem (i :> ix) = i * totalElem ix {-# INLINE [1] totalElem #-} consDim = (:>)@@ -371,13 +369,13 @@ unsnocDim (i :> ix) = case unsnocDim ix of (jx, j) -> (i :> jx, j) {-# INLINE [1] unsnocDim #-}- getIndex ix@(j :> jx) k | k == rank ix = Just j+ getIndex ix@(j :> jx) k | k == dimensions ix = Just j | otherwise = getIndex jx k {-# INLINE [1] getIndex #-}- setIndex ix@(j :> jx) k o | k == rank ix = Just (o :> jx)+ setIndex ix@(j :> jx) k o | k == dimensions ix = Just (o :> jx) | otherwise = (j :>) <$> setIndex jx k o {-# INLINE [1] setIndex #-}- dropDim ix@(j :> jx) k | k == rank ix = Just jx+ dropDim ix@(j :> jx) k | k == dimensions ix = Just jx | otherwise = (j :>) <$> dropDim jx k {-# INLINE [1] dropDim #-} pureIndex i = i :> (pureIndex i :: Ix (n - 1))@@ -457,7 +455,7 @@ -- | Unboxing of a `IxN`. instance (3 <= n, #if __GLASGOW_HASKELL__ < 800- Rank (Ix (n - 1)) ~ (n - 1),+ Dimensions (Ix (n - 1)) ~ (n - 1), #endif VU.Unbox (Ix (n-1))) => VU.Unbox (IxN n) @@ -465,7 +463,7 @@ instance (3 <= n, #if __GLASGOW_HASKELL__ < 800- Rank (Ix (n - 1)) ~ (n - 1),+ Dimensions (Ix (n - 1)) ~ (n - 1), #endif VU.Unbox (Ix (n - 1))) => VM.MVector VU.MVector (IxN n) where@@ -522,7 +520,7 @@ instance (3 <= n, #if __GLASGOW_HASKELL__ < 800- Rank (Ix (n - 1)) ~ (n - 1),+ Dimensions (Ix (n - 1)) ~ (n - 1), #endif VU.Unbox (Ix (n-1))) => V.Vector VU.Vector (IxN n) where basicUnsafeFreeze (MV_IxN (mvec1, mvec)) = do
src/Data/Massiv/Core/List.hs view
@@ -21,6 +21,7 @@ , L(..) , Array(..) , toListArray+ , showArray , ListItem , ShapeError(..) ) where@@ -373,8 +374,22 @@ , Show e ) => Show (Array r ix e) where- show arr =- "(Array " ++ showsTypeRep (typeRep (Proxy :: Proxy r)) " " +++ show arr = showArray (showsTypeRep (typeRep (Proxy :: Proxy r)) " ") arr+ -- "(Array " ++ showsTypeRep (typeRep (Proxy :: Proxy r)) " " +++ -- showComp (getComp arr) ++ " (" +++ -- (show (size arr)) ++ ")\n" +++ -- show (makeArray (getComp arr) (size arr) (evaluateAt arr) :: Array L ix e) ++ ")"+ -- where showComp Seq = "Seq"+ -- showComp Par = "Par"+ -- showComp c = "(" ++ show c ++ ")"++showArray ::+ forall r ix e. (Ragged L ix e, Construct L ix e, Source r ix e, Show e)+ => String+ -> Array r ix e+ -> String+showArray tyStr arr =+ "(Array " ++ tyStr ++ showComp (getComp arr) ++ " (" ++ (show (size arr)) ++ ")\n" ++ show (makeArray (getComp arr) (size arr) (evaluateAt arr) :: Array L ix e) ++ ")"
src/Data/Massiv/Core/Scheduler.hs view
@@ -3,7 +3,7 @@ {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} -- |--- Module : Data.Array.Massiv.Scheduler+-- Module : Data.Massiv.Core.Scheduler -- Copyright : (c) Alexey Kuleshevich 2018 -- License : BSD3 -- Maintainer : Alexey Kuleshevich <lehins@yandex.ru>
− tests/Data/Massiv/Array/MutableSpec.hs
@@ -1,66 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MonoLocalBinds #-}-{-# LANGUAGE MultiParamTypeClasses #-}-module Data.Massiv.Array.MutableSpec (spec) where--import Data.Massiv.CoreArbitrary as A-import Data.Proxy-import Data.Functor.Identity-import Test.Hspec-import Test.QuickCheck-import Test.QuickCheck.Function---prop_MapMapM :: (Show (Array r ix Int), Eq (Array r ix Int), Mutable r ix Int) =>- r -> Proxy ix -> Fun Int Int -> ArrTiny D ix Int -> Property-prop_MapMapM r _ f (ArrTiny arr) =- computeAs r (A.map (apply f) arr) === runIdentity (A.mapM r (return . apply f) arr)--prop_iMapiMapM :: (Show (Array r ix Int), Eq (Array r ix Int), Mutable r ix Int) =>- r -> Proxy ix -> Fun (ix, Int) Int -> ArrTiny D ix Int -> Property-prop_iMapiMapM r _ f (ArrTiny arr) =- computeAs r (A.imap (curry (apply f)) arr) ===- runIdentity (A.imapM r (\ix e -> return $ apply f (ix, e)) arr)---generateSpec :: Spec-generateSpec = do- describe "map == mapM" $ do- describe "P" $ do- it "Ix1" $ property $ prop_MapMapM P (Proxy :: Proxy Ix1)- it "Ix2" $ property $ prop_MapMapM P (Proxy :: Proxy Ix2)- it "Ix3" $ property $ prop_MapMapM P (Proxy :: Proxy Ix3)- describe "U" $ do- it "Ix1" $ property $ prop_MapMapM U (Proxy :: Proxy Ix1)- it "Ix2" $ property $ prop_MapMapM U (Proxy :: Proxy Ix2)- it "Ix3" $ property $ prop_MapMapM U (Proxy :: Proxy Ix3)- describe "S" $ do- it "Ix1" $ property $ prop_MapMapM S (Proxy :: Proxy Ix1)- it "Ix2" $ property $ prop_MapMapM S (Proxy :: Proxy Ix2)- it "Ix3" $ property $ prop_MapMapM S (Proxy :: Proxy Ix3)- describe "B" $ do- it "Ix1" $ property $ prop_MapMapM B (Proxy :: Proxy Ix1)- it "Ix2" $ property $ prop_MapMapM B (Proxy :: Proxy Ix2)- it "Ix3" $ property $ prop_MapMapM B (Proxy :: Proxy Ix3)- describe "imap == imapM" $ do- describe "P" $ do- it "Ix1" $ property $ prop_iMapiMapM P (Proxy :: Proxy Ix1)- it "Ix2T" $ property $ prop_iMapiMapM P (Proxy :: Proxy Ix2T)- it "Ix3T" $ property $ prop_iMapiMapM P (Proxy :: Proxy Ix3T)- describe "U" $ do- it "Ix1" $ property $ prop_iMapiMapM U (Proxy :: Proxy Ix1)- it "Ix2T" $ property $ prop_iMapiMapM U (Proxy :: Proxy Ix2T)- it "Ix3T" $ property $ prop_iMapiMapM U (Proxy :: Proxy Ix3T)- describe "S" $ do- it "Ix1" $ property $ prop_iMapiMapM S (Proxy :: Proxy Ix1)- it "Ix2T" $ property $ prop_iMapiMapM S (Proxy :: Proxy Ix2T)- it "Ix3T" $ property $ prop_iMapiMapM S (Proxy :: Proxy Ix3T)- describe "B" $ do- it "Ix1" $ property $ prop_iMapiMapM B (Proxy :: Proxy Ix1)- it "Ix2T" $ property $ prop_iMapiMapM B (Proxy :: Proxy Ix2T)- it "Ix3T" $ property $ prop_iMapiMapM B (Proxy :: Proxy Ix3T)---spec :: Spec-spec = describe "GenerateM" generateSpec
tests/Data/Massiv/Array/Ops/SliceSpec.hs view
@@ -40,7 +40,7 @@ prop_SliceRight :: (Arbitrary (Array r ix e), Slice r ix e, OuterSlice r ix e, Eq (Elt r ix e)) => proxy (r, ix, e) -> Int -> Array r ix e -> Bool-prop_SliceRight _ i arr = (arr !?> i) == (arr <!?> (rank (size arr), i))+prop_SliceRight _ i arr = (arr !?> i) == (arr <!?> (dimensions (size arr), i)) prop_SliceLeft :: (Arbitrary (Array r ix e), Slice r ix e, InnerSlice r ix e, Eq (Elt r ix e))
tests/Data/Massiv/Array/StencilSpec.hs view
@@ -1,12 +1,13 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MonoLocalBinds #-}-{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE OverloadedLists #-} {-# LANGUAGE MultiParamTypeClasses #-} module Data.Massiv.Array.StencilSpec (spec) where import Control.DeepSeq (deepseq) import Data.Massiv.Array.Stencil+import Data.Massiv.Array.Delayed import Data.Massiv.CoreArbitrary as A import Data.Maybe (fromJust) import Data.Proxy@@ -14,29 +15,30 @@ import Test.QuickCheck import Test.QuickCheck.Function import Data.Default (Default(def))--- sum3x3Stencil :: (Default a, Fractional a) => Border a -> Stencil Ix2 a a--- sum3x3Stencil b = mkConvolutionStencil b (3 :. 3) (1 :. 1) $ \ get ->++-- sum3x3Stencil :: Fractional a => Stencil Ix2 a a+-- sum3x3Stencil = makeConvolutionStencil (3 :. 3) (1 :. 1) $ \ get -> -- get (-1 :. -1) 1 . get (-1 :. 0) 1 . get (-1 :. 1) 1 . -- get ( 0 :. -1) 1 . get ( 0 :. 0) 1 . get ( 0 :. 1) 1 . -- get ( 1 :. -1) 1 . get ( 1 :. 0) 1 . get ( 1 :. 1) 1 -- {-# INLINE sum3x3Stencil #-} -singletonStencil :: (Num ix, Index ix) => (Int -> Int) -> Border Int -> Stencil ix Int Int-singletonStencil f b = makeStencil b 1 0 $ \ get -> fmap f (get zeroIndex)+singletonStencil :: (Num ix, Index ix) => (Int -> Int) -> Stencil ix Int Int+singletonStencil f = makeStencil 1 0 $ \ get -> fmap f (get zeroIndex) {-# INLINE singletonStencil #-} prop_MapSingletonStencil :: (Load DW ix Int, Manifest U ix Int, Num ix) => Proxy ix -> Fun Int Int -> Border Int -> ArrP U ix Int -> Bool prop_MapSingletonStencil _ f b (ArrP arr) =- computeAs U (mapStencil (singletonStencil (apply f) b) arr) == computeAs U (A.map (apply f) arr)+ computeAs U (mapStencil b (singletonStencil (apply f)) arr) == computeAs U (A.map (apply f) arr) -- Tests out of bounds stencil indexing prop_DangerousStencil ::- Index ix => Proxy ix -> NonZero Int -> DimIx ix -> Border Int -> SzIx ix -> Property-prop_DangerousStencil _ (NonZero s) (DimIx r) b (SzIx (Sz sz) ix) =- ix' `deepseq` assertSomeException $ makeStencil b sz ix $ \get -> get ix'+ Index ix => Proxy ix -> NonZero Int -> DimIx ix -> SzIx ix -> Property+prop_DangerousStencil _ (NonZero s) (DimIx r) (SzIx (Sz sz) ix) =+ ix' `deepseq` assertSomeException $ makeStencil sz ix $ \get -> (get ix' :: Value Int) where ix' = liftIndex (* signum s) $@@ -45,7 +47,6 @@ setIndex zeroIndex r i - stencilSpec :: Spec stencilSpec = do describe "MapSingletonStencil" $ do@@ -58,34 +59,22 @@ it "Ix2" $ property $ prop_DangerousStencil (Proxy :: Proxy Ix2) it "Ix3" $ property $ prop_DangerousStencil (Proxy :: Proxy Ix3) it "Ix4" $ property $ prop_DangerousStencil (Proxy :: Proxy Ix4)--- describe "Storable" $ do--- it "Ix1" $ property $ prop_toFromVector (Nothing :: Maybe Ix1) S--- it "Ix2" $ property $ prop_toFromVector (Nothing :: Maybe Ix2) S--- it "Ix3" $ property $ prop_toFromVector (Nothing :: Maybe Ix3) S--- describe "Primitive" $ do--- it "Ix1" $ property $ prop_toFromVector (Nothing :: Maybe Ix1) P--- it "Ix2" $ property $ prop_toFromVector (Nothing :: Maybe Ix2) P--- it "Ix3" $ property $ prop_toFromVector (Nothing :: Maybe Ix3) P--- describe "Boxed" $ do--- it "Ix1" $ property $ prop_toFromVector (Nothing :: Maybe Ix1) B--- it "Ix2" $ property $ prop_toFromVector (Nothing :: Maybe Ix2) B--- it "Ix3" $ property $ prop_toFromVector (Nothing :: Maybe Ix3) B stencilDirection :: (Default a, Unbox a, Manifest r Ix2 a) => Ix2 -> Array r Ix2 a -> Array U Ix2 a-stencilDirection ix = computeAs U . mapStencil (makeStencil (Fill def) (3 :. 3) (1 :. 1) $ \f -> f ix)+stencilDirection ix = computeAs U . mapStencil (Fill def) (makeStencil (3 :. 3) (1 :. 1) $ \f -> f ix) stencilCorners :: (Default a, Unbox a, Manifest r Ix2 a) => Ix2 -> Ix2 -> Array r Ix2 a -> Array U Ix2 a-stencilCorners ixC ix = computeAs U . mapStencil (makeStencil (Fill def) (3 :. 3) ixC $ \f -> f ix)+stencilCorners ixC ix = computeAs U . mapStencil (Fill def) (makeStencil (3 :. 3) ixC $ \f -> f ix) spec :: Spec spec = do describe "Stencil" $ do stencilSpec+ let arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] :: Array U Ix2 Int describe "Unit tests Ix2" $ do- let arr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] :: Array U Ix2 Int it "Direction Left" $ stencilDirection (0 :. 1) arr `shouldBe` [[2, 3, 0], [5, 6, 0], [8, 9, 0]] it "Direction Right" $@@ -102,3 +91,37 @@ stencilCorners (2 :. 2) (-2 :. -2) arr `shouldBe` [[0, 0, 0], [0, 0, 0], [0, 0, 1]] it "Direction Left/Bottom Corner" $ stencilCorners (2 :. 0) (-2 :. 2) arr `shouldBe` [[0, 0, 0], [0, 0, 0], [3, 0, 0]]+ describe "reformDW" $ do+ it "map stencil with stride on small array" $+ let kernel = [[-1, 0, 1], [0, 1, 0], [-1, 0, 1]] :: Array U Ix2 Int+ stencil = makeConvolutionStencilFromKernel kernel+ stride = 2+ strideArr = mapStride stride (1 :. 1) $ mapStencil (Fill 0) stencil arr+ in computeAs U strideArr `shouldBe` [[-4]]+ it "map stencil with stride on larger array" $+ let kernel = [[-1, 0, 1], [0, 1, 0], [-1, 0, 1]] :: Array U Ix2 Int+ stencil = makeConvolutionStencilFromKernel kernel+ stride = 2+ largeArr = makeArrayR U Seq (5 :. 5) (succ . toLinearIndex (5 :. 5))+ stencilledArr = mapStencil (Fill 0) stencil largeArr+ strideArr = mapStride stride (2 :. 2) stencilledArr+ in do computeAs U strideArr `shouldBe` [[-6, 1], [-13, 9]]+ it "resize DWArray resulting from mapStencil" $+ let kernel = [[-1, 0, 1], [0, 1, 0], [-1, 0, 1]] :: Array U Ix2 Int+ stencil = makeConvolutionStencilFromKernel kernel+ result = unsafeBackpermuteDW (+1) (subtract 1) (5 :. 5) $ mapStencil (Fill 0) stencil arr+ expectation =+ [ [ -1, -2, -2, 2, 3]+ , [ -4, -4, 0, 8, 6]+ , [ -8, -6, 1, 16, 12]+ , [ -4, 2, 6, 14, 6]+ , [ -7, -8, -2, 8, 9]+ ]+ in computeAs U result `shouldBe` expectation++mapStride :: Index ix => Int -> ix -> Array DW ix e -> Array DW ix e+mapStride stride sz =+ let toOldIndex = liftIndex (* stride)+ ceilingDivStride a = ceiling $ (fromIntegral a :: Double) / fromIntegral stride+ toNewIndex = liftIndex ceilingDivStride+ in unsafeBackpermuteDW toNewIndex toOldIndex sz
tests/Data/Massiv/Core/IndexSpec.hs view
@@ -60,7 +60,7 @@ instance Index ix => Arbitrary (DimIx ix) where arbitrary = do n <- arbitrary- return $ DimIx (1 + (Dim n `mod` (rank (undefined :: ix))))+ return $ DimIx (1 + (Dim n `mod` (dimensions (undefined :: ix)))) instance Arbitrary Ix2 where arbitrary = (:.) <$> arbitrary <*> arbitrary@@ -110,13 +110,15 @@ prop_CountElements :: Index ix => proxy ix -> Int -> Sz ix -> Property prop_CountElements _ thresh (Sz sz) =- totalElem sz < thresh ==> totalElem sz == iter zeroIndex sz 1 (<) 0 (\ _ acc -> (acc + 1))+ totalElem sz < thresh ==> totalElem sz ==+ iter zeroIndex sz (pureIndex 1) (<) 0 (\_ acc -> (acc + 1)) prop_IterMonotonic :: Index ix => proxy ix -> Int -> Sz ix -> Property prop_IterMonotonic _ thresh (Sz sz) = totalElem sz < thresh ==> fst $- iter (liftIndex succ zeroIndex) sz 1 (<) (True, zeroIndex) $ \ curIx (prevMono, prevIx) ->- let isMono = prevMono && prevIx < curIx in isMono `seq` (isMono, curIx)+ iter (liftIndex succ zeroIndex) sz (pureIndex 1) (<) (True, zeroIndex) $ \curIx (prevMono, prevIx) ->+ let isMono = prevMono && prevIx < curIx+ in isMono `seq` (isMono, curIx) prop_IterMonotonic' :: Index ix => proxy ix -> Int -> Sz ix -> Property@@ -128,7 +130,7 @@ else error (show a) where (isM, a, _) =- iter (liftIndex succ zeroIndex) sz 1 (<) (True, [], zeroIndex) $+ iter (liftIndex succ zeroIndex) sz (pureIndex 1) (<) (True, [], zeroIndex) $ \ curIx (prevMono, acc, prevIx) -> let nAcc = (prevIx, curIx, prevIx < curIx) : acc isMono = prevMono && prevIx < curIx@@ -144,7 +146,7 @@ else error (show a) where (isM, a, _) =- iter (liftIndex pred sz) zeroIndex (-1) (>=) (True, [], sz) $+ iter (liftIndex pred sz) zeroIndex (pureIndex (-1)) (>=) (True, [], sz) $ \ curIx (prevMono, acc, prevIx) -> let isMono = prevMono && prevIx > curIx nAcc = (prevIx, curIx, prevIx > curIx) : acc@@ -154,7 +156,7 @@ prop_IterMonotonicM _ thresh (Sz sz) = totalElem sz < thresh ==> fst $ runIdentity $- iterM (liftIndex succ zeroIndex) sz 1 (<) (True, zeroIndex) $ \curIx (prevMono, prevIx) ->+ iterM (liftIndex succ zeroIndex) sz (pureIndex 1) (<) (True, zeroIndex) $ \curIx (prevMono, prevIx) -> let isMono = prevMono && prevIx < curIx in return $ isMono `seq` (isMono, curIx) @@ -162,13 +164,13 @@ prop_IterMonotonicBackwards :: Index ix => proxy ix -> Int -> Sz ix -> Property prop_IterMonotonicBackwards _ thresh (Sz sz) = totalElem sz < thresh ==> fst $- iter (liftIndex pred sz) zeroIndex (-1) (>=) (True, sz) $ \ curIx (prevMono, prevIx) ->+ iter (liftIndex pred sz) zeroIndex (pureIndex (-1)) (>=) (True, sz) $ \ curIx (prevMono, prevIx) -> let isMono = prevMono && prevIx > curIx in isMono `seq` (isMono, curIx) prop_IterMonotonicBackwardsM :: Index ix => proxy ix -> Int -> Sz ix -> Property prop_IterMonotonicBackwardsM _ thresh (Sz sz) = totalElem sz < thresh ==> fst $ runIdentity $- iterM (liftIndex pred sz) zeroIndex (-1) (>=) (True, sz) $ \ curIx (prevMono, prevIx) ->+ iterM (liftIndex pred sz) zeroIndex (pureIndex (-1)) (>=) (True, sz) $ \ curIx (prevMono, prevIx) -> let isMono = prevMono && prevIx > curIx in return $ isMono `seq` (isMono, curIx) prop_LiftLift2 :: Index ix => proxy ix -> ix -> Int -> Bool@@ -190,8 +192,8 @@ prop_UnconsGetDrop :: (Index (Lower ix), Index ix) => proxy ix -> ix -> Bool prop_UnconsGetDrop _ ix = Just (unconsDim ix) == do- i <- getIndex ix (rank ix)- ixL <- dropDim ix (rank ix)+ i <- getIndex ix (dimensions ix)+ ixL <- dropDim ix (dimensions ix) return (i, ixL) prop_UnsnocGetDrop :: (Index (Lower ix), Index ix) => proxy ix -> ix -> Bool@@ -203,7 +205,7 @@ prop_SetAll :: Index ix => proxy ix -> ix -> Int -> Bool prop_SetAll _ ix i =- foldM (\cix d -> setIndex cix d i) ix ([1 .. rank ix] :: [Dim]) ==+ foldM (\cix d -> setIndex cix d i) ix ([1 .. dimensions ix] :: [Dim]) == Just (pureIndex i)
tests/Spec.hs view
@@ -2,7 +2,7 @@ import Data.Massiv.Array.DelayedSpec as Delayed import Data.Massiv.Array.Manifest.VectorSpec as Vector-import Data.Massiv.Array.MutableSpec as Mutable+--import Data.Massiv.Array.MutableSpec as Mutable import Data.Massiv.Array.Ops.ConstructSpec as Construct import Data.Massiv.Array.Ops.FoldSpec as Fold import Data.Massiv.Array.Ops.SliceSpec as Slice@@ -29,6 +29,6 @@ Slice.spec Transform.spec describe "Delayed" $ Delayed.spec- describe "Mutable" $ Mutable.spec+ --describe "Mutable" $ Mutable.spec describe "Stencil" $ Stencil.spec describe "Vector" $ Vector.spec