Skip to content

Commit 8dee340

Browse files
use Control.Monad.Par to resolve race conditions; introduce 4-ary parallelism operator
1 parent 2e76158 commit 8dee340

File tree

2 files changed

+44
-5
lines changed

2 files changed

+44
-5
lines changed

src/DpsMergeSort4Par.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,10 @@ msortInplace src tmp =
5555
!(tmp1, tmp2) = splitMid tmpA
5656
!(tmp3, tmp4) = splitMid tmpB
5757
!(((src1', tmp1'), (src2', tmp2')), ((src3', tmp3'), (src4', tmp4')))
58-
= (msortInplace src1 tmp1 .||. msortInplace src2 tmp2) .||.
59-
(msortInplace src3 tmp3 .||. msortInplace src4 tmp4)
58+
= (.||||.) (msortInplace src1 tmp1) (msortInplace src2 tmp2)
59+
(msortInplace src3 tmp3) (msortInplace src4 tmp4)
60+
-- = (msortInplace src1 tmp1 .||. msortInplace src2 tmp2) .||.
61+
-- (msortInplace src3 tmp3 .||. msortInplace src4 tmp4)
6062
-- = tuple4 (msortInplace src1) tmp1 (msortInplace src2) tmp2
6163
-- (msortInplace src3) tmp3 (msortInplace src4) tmp4
6264
tmpA' = A.append tmp1' tmp2'

src/Par.hs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Linear.Common
88
import qualified Unsafe.Linear as Unsafe
99
import Control.DeepSeq ( NFData(..) )
1010
import GHC.Conc ( par, pseq )
11+
import qualified Control.Monad.Par as P
1112

1213
--------------------------------------------------------------------------------
1314

@@ -37,9 +38,39 @@ tuple4 f1 x f2 y f3 z f4 a = p `par` q `par` r `par` s `pseq` ((p,q), (r,s))
3738
r = f3 z
3839
s = f4 a
3940

40-
{-# INLINE (.||.) #-}
41-
(.||.) :: (NFData a, NFData b) => a -. b -. (a,b)
42-
(.||.) = Unsafe.toLinear (\a -> Unsafe.toLinear (\b -> (a `par` b `pseq` (a,b))))
41+
{-# INLINABLE (.||.) #-}
42+
(.||.) :: (NFData a) => a -. a -. (a,a)
43+
--(.||.) = Unsafe.toLinear (\a -> Unsafe.toLinear (\b -> (a `par` b `pseq` (a,b))))
44+
(.||.) = Unsafe.toLinear (\a -> Unsafe.toLinear (\b -> P.runPar $ do
45+
i <- P.new
46+
j <- P.new
47+
P.fork (P.put_ i a)
48+
P.fork (P.put_ j b)
49+
a' <- P.get i
50+
b' <- P.get j
51+
return (a', b')
52+
))
53+
54+
55+
(.||||.) :: (NFData a) => a -. a -. a -. a -. ((a,a),(a,a))
56+
(.||||.) = Unsafe.toLinear (\a ->
57+
Unsafe.toLinear (\b ->
58+
Unsafe.toLinear (\c ->
59+
Unsafe.toLinear (\d -> P.runPar $ do
60+
i <- P.new
61+
j <- P.new
62+
k <- P.new
63+
l <- P.new
64+
P.fork (P.put_ i a)
65+
P.fork (P.put_ j b)
66+
P.fork (P.put_ k c)
67+
P.fork (P.put_ l d)
68+
a' <- P.get i
69+
b' <- P.get j
70+
c' <- P.get k
71+
d' <- P.get l
72+
return ((a', b'), (c', d'))
73+
))))
4374

4475
{-
4576
tuple2 :: (NFData a, NFData b) => (a -> b) -> a -> (a -> b) -> a -> (b, b)
@@ -88,4 +119,10 @@ tuple4 f x g y h z j w = ((f x, g y), (h z, j w))
88119
{-@ (.||.) :: x:a -> y:b -> { tup:_ | x == fst tup && y = snd tup } @-}
89120
(.||.) :: a -. b -. (a,b)
90121
a .||. b = (a,b)
122+
123+
{-@ (.||||.) :: x:a -> y:a -> z:a -> w:a
124+
-> { tup:_ | x == fst (fst tup) && y == snd (fst tup) &&
125+
z == fst (snd tup) && w == snd (snd tup) } @-}
126+
(.||||.) :: (NFData a) => a -. a -. a -. a -. ((a,a),(a,a))
127+
(.||||.) a b c d = ((a, b), (c, d))
91128
#endif

0 commit comments

Comments
 (0)