Skip to content

Commit

Permalink
Bunch of mutable stuff and hie settings:
Browse files Browse the repository at this point in the history
* Rename `msize` -> `sizeOfMArray`
* Add `unsafeResizeMArray` and `unsafeLinearSliceMArray`
* Rename:
  * `loadArrayM` -> `iterArrayLinearM_`
  * `loadArrayWithSetM` -> `iterArrayLinearWithSetM_`.
  * `loadArrayWithStrideM` -> `iterArrayLinearWithStrideM_`.
* Add `iterArrayLinearST_` and `iterArrayLinearWithSetST_` to `Load` class instead
  of `loadArrayM` and `loadArrayWithSetM`.
* Add `iterArrayLinearWithStrideST_` to `LoadStride` class instead of `loadArrayWithStrideM`.
* Add new mutable functions:
  * `resizeMArrayM`,
  * `outerSliceMArrayM` and `outerSlicesMArray`,
  * `for2PrimM_` and `ifor2PrimM_`,
  * `zipSwapM_`
* Switch effectful mapping functions to use the representation specific
  iterators. Which means that they are now restricted to `Load` instead of
  `Source`. Functions affected:
  * `mapIO_`, `imapIO_`, `forIO_` and `iforIO_`
  * `mapIO`, `imapIO`, `forIO` and `iforIO`
  • Loading branch information
lehins committed Jul 31, 2021
1 parent 90e04d2 commit 99f162f
Show file tree
Hide file tree
Showing 32 changed files with 683 additions and 294 deletions.
5 changes: 0 additions & 5 deletions cabal.project

This file was deleted.

10 changes: 10 additions & 0 deletions hie.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
cradle:
stack:
#stackYaml: "./stack-extra-deps.yaml"
components:
- path: "./massiv/src"
component: "massiv:lib"
- path: "./massiv-test/src"
component: "massiv-test:lib"
- path: "./massiv-tests/tests"
component: "massiv-test:test:tests-O0"
2 changes: 1 addition & 1 deletion massiv-bench/bench/Concat.hs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ concatMutableM arrsF =
unsafeCreateArray_ (foldMap getComp arrsF) newSz $ \scheduler marr -> do
let arrayLoader !offset arr = do
scheduleWork scheduler $ do
stToIO $ loadArrayM scheduler arr (\i -> unsafeLinearWrite marr (i + offset))
stToIO $ iterArrayLinearST scheduler arr (\i -> unsafeLinearWrite marr (i + offset))
pure (offset + totalElem (size arr))
foldM_ arrayLoader 0 $ a : arrs
{-# INLINE concatMutableM #-}
Expand Down
2 changes: 2 additions & 0 deletions massiv-bench/hie.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cradle:
stack:
13 changes: 13 additions & 0 deletions massiv-bench/stack-ghc-8.8.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
resolver: lts-16.22
packages:
- '.'
extra-deps:
- '../massiv/'
- primitive-0.7.1.0@sha256:29de6bfd0cf8ba023ceb806203dfbec0e51e3524e75ffe41056f70b4229c6f0f,2728
- random-1.2.0@sha256:195506fedaa7c31c1fa2a747e9b49b4a5d1f0b09dd8f1291f23a771656faeec3,6097
- splitmix-0.1.0.3@sha256:fc3aae74c467f4b608050bef53aec17904a618731df9407e655d8f3bf8c32d5c,6049
#- scheduler-1.4.0@sha256:b182be9a7b84e1dba02dac761c3f4e204521d0f779d72d86040789d5aaadf92a,2833
- github: lehins/haskell-scheduler
commit: c5506d20d96fc3fb00c213791243b7246d39e822
subdirs:
- scheduler
9 changes: 9 additions & 0 deletions massiv-bench/stack-ghc-9.0.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
resolver: lts-18.3
packages:
- '.'
extra-deps:
- '../massiv/'
- github: lehins/haskell-scheduler
commit: c5506d20d96fc3fb00c213791243b7246d39e822
subdirs:
- scheduler
2 changes: 1 addition & 1 deletion massiv-test/src/Test/Massiv/Core/Mutable.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ prop_UnsafeNewMsize ::
=> Property
prop_UnsafeNewMsize = property $ \ sz -> do
marr :: MArray RealWorld r ix e <- unsafeNew sz
sz `shouldBe` msize marr
sz `shouldBe` sizeOfMArray marr

prop_UnsafeNewLinearWriteRead ::
forall r ix e.
Expand Down
19 changes: 19 additions & 0 deletions massiv/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,25 @@
* Change function argument to monadic action for `unstablePartitionM` and `unsafeUnstablePartitionM`
* Replace `snull` with a more generic `isNull`
* Switch `DL` loading function to run in `ST` monad, rather than in any `Monad m`.
* Rename `msize` -> `sizeOfMArray`
* Add `unsafeResizeMArray` and `unsafeLinearSliceMArray`
* Rename:
* `loadArrayM` -> `iterArrayLinearM_`
* `loadArrayWithSetM` -> `iterArrayLinearWithSetM_`.
* `loadArrayWithStrideM` -> `iterArrayLinearWithStrideM_`.
* Add `iterArrayLinearST_` and `iterArrayLinearWithSetST_` to `Load` class instead
of `loadArrayM` and `loadArrayWithSetM`.
* Add `iterArrayLinearWithStrideST_` to `LoadStride` class instead of `loadArrayWithStrideM`.
* Add new mutable functions:
* `resizeMArrayM`,
* `outerSliceMArrayM` and `outerSlicesMArray`,
* `for2PrimM_` and `ifor2PrimM_`,
* `zipSwapM_`
* Switch effectful mapping functions to use the representation specific
iteration. Which means that they are now restricted to `Load` instead of
`Source`. Functions affected:
* `mapIO_`, `imapIO_`, `forIO_` and `iforIO_`
* `mapIO`, `imapIO`, `forIO` and `iforIO`

# 0.6.1

Expand Down
8 changes: 4 additions & 4 deletions massiv/src/Data/Massiv/Array/Delayed/Interleaved.hs
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,21 @@ instance Resize DI where
instance Index ix => Load DI ix e where
makeArray c sz = DIArray . makeArray c sz
{-# INLINE makeArray #-}
loadArrayM scheduler (DIArray (DArray _ sz f)) uWrite =
iterArrayLinearST_ scheduler (DIArray (DArray _ sz f)) uWrite =
loopM_ 0 (< numWorkers scheduler) (+ 1) $ \ !start ->
scheduleWork scheduler $
iterLinearM_ sz start (totalElem sz) (numWorkers scheduler) (<) $ \ !k -> uWrite k . f
{-# INLINE loadArrayM #-}
{-# INLINE iterArrayLinearST_ #-}

instance Index ix => StrideLoad DI ix e where
loadArrayWithStrideM scheduler stride resultSize arr uWrite =
iterArrayLinearWithStrideST_ scheduler stride resultSize arr uWrite =
let strideIx = unStride stride
DIArray (DArray _ _ f) = arr
in loopM_ 0 (< numWorkers scheduler) (+ 1) $ \ !start ->
scheduleWork scheduler $
iterLinearM_ resultSize start (totalElem resultSize) (numWorkers scheduler) (<) $
\ !i ix -> uWrite i (f (liftIndex2 (*) strideIx ix))
{-# INLINE loadArrayWithStrideM #-}
{-# INLINE iterArrayLinearWithStrideST_ #-}

-- | Convert a source array into an array that, when computed, will have its elemets evaluated out
-- of order (interleaved amongst cores), hence making unbalanced computation better parallelizable.
Expand Down
5 changes: 3 additions & 2 deletions massiv/src/Data/Massiv/Array/Delayed/Pull.hs
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,9 @@ instance Index ix => Foldable (Array D ix) where
instance Index ix => Load D ix e where
makeArray = DArray
{-# INLINE makeArray #-}
loadArrayM !scheduler !arr = splitLinearlyWith_ scheduler (elemsCount arr) (unsafeLinearIndex arr)
{-# INLINE loadArrayM #-}
iterArrayLinearST_ !scheduler !arr =
splitLinearlyWith_ scheduler (elemsCount arr) (unsafeLinearIndex arr)
{-# INLINE iterArrayLinearST_ #-}

instance Index ix => StrideLoad D ix e

Expand Down
26 changes: 11 additions & 15 deletions massiv/src/Data/Massiv/Array/Delayed/Push.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,18 @@ import Prelude hiding (map, zipWith)
-- | Delayed load representation. Also known as Push array.
data DL = DL deriving Show

type Loader e
= forall s. Scheduler s ()
-> Ix1
-> (Ix1 -> e -> ST s ())
-> (Ix1 -> Sz1 -> e -> ST s ())
-> ST s ()
type Loader e =
forall s. Scheduler s () -- ^ Scheduler that will be used for loading
-> Ix1 -- ^ Start loading at this linear index
-> (Ix1 -> e -> ST s ()) -- ^ Linear element writing action
-> (Ix1 -> Sz1 -> e -> ST s ()) -- ^ Linear region setting action
-> ST s ()


data instance Array DL ix e = DLArray
{ dlComp :: !Comp
, dlSize :: !(Sz ix)
, dlLoad :: forall s. Scheduler s ()
-> Ix1 -- start loading at this linear index
-> (Ix1 -> e -> ST s ()) -- linear element writing action
-> (Ix1 -> Sz1 -> e -> ST s ()) -- linear region setting action
-> ST s ()
, dlLoad :: Loader e
}

instance Strategy DL where
Expand Down Expand Up @@ -294,7 +290,7 @@ toLoadArray arr = DLArray (getComp arr) sz load
load :: forall s.
Scheduler s () -> Ix1 -> (Ix1 -> e -> ST s ()) -> (Ix1 -> Sz1 -> e -> ST s ()) -> ST s ()
load scheduler !startAt dlWrite dlSet =
loadArrayWithSetM scheduler arr (dlWrite . (+ startAt)) (\offset -> dlSet (offset + startAt))
iterArrayLinearWithSetST_ scheduler arr (dlWrite . (+ startAt)) (\offset -> dlSet (offset + startAt))
{-# INLINE load #-}
{-# INLINE[1] toLoadArray #-}
{-# RULES "toLoadArray/id" toLoadArray = id #-}
Expand All @@ -313,7 +309,7 @@ fromStrideLoad stride arr =
!newsz = strideSize stride (size arr)
load :: Loader e
load scheduler !startAt dlWrite _ =
loadArrayWithStrideM scheduler stride newsz arr (\ !i -> dlWrite (i + startAt))
iterArrayLinearWithStrideST_ scheduler stride newsz arr (\ !i -> dlWrite (i + startAt))
{-# INLINE load #-}
{-# INLINE fromStrideLoad #-}

Expand All @@ -327,8 +323,8 @@ instance Index ix => Load DL ix e where
{-# INLINE makeArrayLinear #-}
replicate comp !sz !e = makeLoadArray comp sz e $ \_ _ -> pure ()
{-# INLINE replicate #-}
loadArrayWithSetM scheduler DLArray {dlLoad} = dlLoad scheduler 0
{-# INLINE loadArrayWithSetM #-}
iterArrayLinearWithSetST_ scheduler DLArray {dlLoad} = dlLoad scheduler 0
{-# INLINE iterArrayLinearWithSetST_ #-}

instance Index ix => Functor (Array DL ix) where
fmap f arr = arr {dlLoad = loadFunctor arr f}
Expand Down
25 changes: 12 additions & 13 deletions massiv/src/Data/Massiv/Array/Delayed/Stream.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ module Data.Massiv.Array.Delayed.Stream
) where

import Control.Applicative
import Control.Monad (void)
import Control.Monad.ST
import Data.Coerce
import Data.Foldable
Expand Down Expand Up @@ -193,19 +192,19 @@ instance Load DS Ix1 e where
replicate _ k = fromSteps . S.replicate k
{-# INLINE replicate #-}

loadArrayM _scheduler arr uWrite =
case stepsSize (dsArray arr) of
LengthExact _ ->
void $ S.foldlM (\i e -> uWrite i e >> pure (i + 1)) 0 (S.transStepsId (coerce arr))
_ -> error "Loading Stream array is not supported with loadArrayM"
{-# INLINE loadArrayM #-}
iterArrayLinearST_ _scheduler arr uWrite =
-- case stepsSize (dsArray arr) of
-- LengthExact _ ->
-- void $ S.foldlM (\i e -> uWrite i e >> pure (i + 1)) 0 (S.transStepsId (coerce arr))
S.mapM_ (uncurry uWrite) $ S.indexed $ S.transStepsId (coerce arr)
{-# INLINE iterArrayLinearST_ #-}

unsafeLoadIntoS marr (DSArray sts) =
unsafeLoadIntoST marr (DSArray sts) =
S.unstreamIntoM marr (stepsSize sts) (stepsStream sts)
{-# INLINE unsafeLoadIntoS #-}
{-# INLINE unsafeLoadIntoST #-}

unsafeLoadIntoM marr arr = stToIO $ unsafeLoadIntoS marr arr
{-# INLINE unsafeLoadIntoM #-}
unsafeLoadIntoIO marr arr = stToIO $ unsafeLoadIntoST marr arr
{-# INLINE unsafeLoadIntoIO #-}


-- cons :: e -> Array DS Ix1 e -> Array DS Ix1 e
Expand All @@ -223,13 +222,13 @@ instance Load DS Ix1 e where

-- TODO: skip the stride while loading
-- instance StrideLoad DS Ix1 e where
-- loadArrayWithStrideM scheduler stride resultSize arr uWrite =
-- iterArrayLinearWithStrideST_ scheduler stride resultSize arr uWrite =
-- let strideIx = unStride stride
-- DIArray (DArray _ _ f) = arr
-- in loopM_ 0 (< numWorkers scheduler) (+ 1) $ \ !start ->
-- scheduleWork scheduler $
-- iterLinearM_ resultSize start (totalElem resultSize) (numWorkers scheduler) (<) $
-- \ !i ix -> uWrite i (f (liftIndex2 (*) strideIx ix))
-- {-# INLINE loadArrayWithStrideM #-}
-- {-# INLINE iterArrayLinearWithStrideST_ #-}


28 changes: 14 additions & 14 deletions massiv/src/Data/Massiv/Array/Delayed/Windowed.hs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ instance Size DW where
instance Load DW Ix1 e where
makeArray c sz f = DWArray (makeArray c sz f) Nothing
{-# INLINE makeArray #-}
loadArrayM scheduler arr uWrite = do
iterArrayLinearST_ scheduler arr uWrite = do
(loadWindow, wStart, wEnd) <- loadWithIx1 (scheduleWork scheduler) arr uWrite
let (chunkWidth, slackWidth) = (wEnd - wStart) `quotRem` numWorkers scheduler
loopM_ 0 (< numWorkers scheduler) (+ 1) $ \ !wid ->
Expand All @@ -226,10 +226,10 @@ instance Load DW Ix1 e where
when (slackWidth > 0) $
let !itSlack = numWorkers scheduler * chunkWidth + wStart
in loadWindow itSlack (itSlack + slackWidth)
{-# INLINE loadArrayM #-}
{-# INLINE iterArrayLinearST_ #-}

instance StrideLoad DW Ix1 e where
loadArrayWithStrideM scheduler stride sz arr uWrite = do
iterArrayLinearWithStrideST_ scheduler stride sz arr uWrite = do
(loadWindow, (wStart, wEnd)) <- loadArrayWithIx1 (scheduleWork scheduler) arr stride sz uWrite
let (chunkWidth, slackWidth) = (wEnd - wStart) `quotRem` numWorkers scheduler
loopM_ 0 (< numWorkers scheduler) (+ 1) $ \ !wid ->
Expand All @@ -238,7 +238,7 @@ instance StrideLoad DW Ix1 e where
when (slackWidth > 0) $
let !itSlack = numWorkers scheduler * chunkWidth + wStart
in loadWindow (itSlack, itSlack + slackWidth)
{-# INLINE loadArrayWithStrideM #-}
{-# INLINE iterArrayLinearWithStrideST_ #-}

loadArrayWithIx1 ::
(Monad m)
Expand Down Expand Up @@ -339,27 +339,27 @@ loadWindowIx2 nWorkers loadWindow (it :. ib) = do
instance Load DW Ix2 e where
makeArray c sz f = DWArray (makeArray c sz f) Nothing
{-# INLINE makeArray #-}
loadArrayM scheduler arr uWrite =
iterArrayLinearST_ scheduler arr uWrite =
loadWithIx2 (scheduleWork scheduler) arr uWrite >>=
uncurry (loadWindowIx2 (numWorkers scheduler))
{-# INLINE loadArrayM #-}
{-# INLINE iterArrayLinearST_ #-}

instance StrideLoad DW Ix2 e where
loadArrayWithStrideM scheduler stride sz arr uWrite =
iterArrayLinearWithStrideST_ scheduler stride sz arr uWrite =
loadArrayWithIx2 (scheduleWork scheduler) arr stride sz uWrite >>=
uncurry (loadWindowIx2 (numWorkers scheduler))
{-# INLINE loadArrayWithStrideM #-}
{-# INLINE iterArrayLinearWithStrideST_ #-}


instance (Index (IxN n), Load DW (Ix (n - 1)) e) => Load DW (IxN n) e where
makeArray c sz f = DWArray (makeArray c sz f) Nothing
{-# INLINE makeArray #-}
loadArrayM = loadWithIxN
{-# INLINE loadArrayM #-}
iterArrayLinearST_ = loadWithIxN
{-# INLINE iterArrayLinearST_ #-}

instance (Index (IxN n), StrideLoad DW (Ix (n - 1)) e) => StrideLoad DW (IxN n) e where
loadArrayWithStrideM = loadArrayWithIxN
{-# INLINE loadArrayWithStrideM #-}
iterArrayLinearWithStrideST_ = loadArrayWithIxN
{-# INLINE iterArrayLinearWithStrideST_ #-}

loadArrayWithIxN ::
(Index ix, StrideLoad DW (Lower ix) e)
Expand Down Expand Up @@ -391,7 +391,7 @@ loadArrayWithIxN scheduler stride szResult arr uWrite = do
DWArray
{dwArray = DArray Seq lowerSourceSize (indexBorder . consDim i), dwWindow = ($ i) <$> mw}
loadLower mw !i =
loadArrayWithStrideM
iterArrayLinearWithStrideST_
scheduler
(Stride lowerStrideIx)
lowerSize
Expand Down Expand Up @@ -434,7 +434,7 @@ loadWithIxN scheduler arr uWrite = do
DWArray {dwArray = DArray Seq szL (indexBorder . consDim i), dwWindow = ($ i) <$> mw}
loadLower mw !i =
scheduleWork_ scheduler $
loadArrayM scheduler (mkLowerArray mw i) (\k -> uWrite (k + pageElements * i))
iterArrayLinearST_ scheduler (mkLowerArray mw i) (\k -> uWrite (k + pageElements * i))
{-# NOINLINE loadLower #-}
loopM_ 0 (< headDim windowStart) (+ 1) (loadLower Nothing)
loopM_ t (< headDim windowEnd) (+ 1) (loadLower (Just mkLowerWindow))
Expand Down
Loading

0 comments on commit 99f162f

Please sign in to comment.