Skip to content

Commit 04758ea

Browse files
fix cilksort segfault/slowness
1 parent f49363b commit 04758ea

File tree

1 file changed

+52
-31
lines changed

1 file changed

+52
-31
lines changed

src/CilkSort.hs

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -43,37 +43,56 @@ cilkSortInplace :: (Show a, HasPrimOrd a, NFData a) =>
4343
cilkSortInplace :: (Show a, HasPrimOrd a) =>
4444
#endif
4545
A.Array a -. A.Array a -. (A.Array a, A.Array a)
46-
cilkSortInplace src tmp =
47-
let !(Ur len, src') = A.size2 src in
48-
if len <= SEQSIZE
49-
then
50-
if len <= QUICKSIZE
51-
then let src'' = quickSort src'
52-
in (src'', tmp)
53-
else Seq.msortInplace src' tmp
54-
else
55-
let !(srcA, srcB) = splitMid src'
56-
!(tmpA, tmpB) = splitMid tmp
57-
!(src1, src2) = splitMid srcA
58-
!(src3, src4) = splitMid srcB
59-
!(tmp1, tmp2) = splitMid tmpA
60-
!(tmp3, tmp4) = splitMid tmpB
61-
!(((src1', tmp1'), (src2', tmp2')), ((src3', tmp3'), (src4', tmp4')))
62-
= (.||||.) (cilkSortInplace src1 tmp1) (cilkSortInplace src2 tmp2)
63-
(cilkSortInplace src3 tmp3) (cilkSortInplace src4 tmp4)
64-
tmpA' = A.append tmp1' tmp2'
65-
tmpB' = A.append tmp3' tmp4'
66-
!((srcA'', tmpA''), (srcB'', tmpB''))
67-
= merge_par src1' src2' tmpA' .||. merge_par src3' src4' tmpB'
68-
-- = tuple2 (merge_par src1' src2') tmpA' (merge_par src3' src4') tmpB'
69-
src'' = A.append srcA'' srcB''
70-
!(tmp''', src''') = merge_par tmpA'' tmpB'' src''
71-
in (src''', tmp''') ? lem_toBag_splitMid src
72-
? lem_toBag_splitMid tmp
73-
? lem_toBag_splitMid srcA
74-
? lem_toBag_splitMid srcB
75-
? lem_toBag_splitMid tmpA
76-
? lem_toBag_splitMid tmpB
46+
cilkSortInplace src tmp = go src tmp where
47+
{-@ go ::xs:Array a
48+
-> { ys:(Array a ) | A.size ys == A.size xs && left xs == left ys &&
49+
right xs == right ys }
50+
-> (Array a, Array a)<{\zs ts -> toBag xs == toBag zs && isSorted' zs &&
51+
token xs == token zs && token ys == token ts &&
52+
A.size xs == A.size zs && A.size ys == A.size ts &&
53+
left zs == left xs && right zs == right xs &&
54+
left ts == left ys && right ts == right ys }>
55+
/ [A.size xs] @-}
56+
#ifdef MUTABLE_ARRAYS
57+
go :: (Show a, HasPrimOrd a, NFData a) =>
58+
#else
59+
go :: (Show a, HasPrimOrd a) =>
60+
#endif
61+
A.Array a -. A.Array a -. (A.Array a, A.Array a)
62+
go src tmp =
63+
let !(Ur len, src') = A.size2 src in
64+
if len <= SEQSIZE
65+
then
66+
if len <= QUICKSIZE
67+
then let src'' = quickSort' src'
68+
in (src'', tmp)
69+
else Seq.msortInplace src' tmp
70+
else
71+
let !(srcA, srcB) = splitMid src'
72+
!(tmpA, tmpB) = splitMid tmp
73+
!(src1, src2) = splitMid srcA
74+
!(src3, src4) = splitMid srcB
75+
!(tmp1, tmp2) = splitMid tmpA
76+
!(tmp3, tmp4) = splitMid tmpB
77+
!(((src1', tmp1'), (src2', tmp2')), ((src3', tmp3'), (src4', tmp4')))
78+
= (go src1 tmp1 .||. go src2 tmp2) .||.
79+
(go src3 tmp3 .||. go src4 tmp4)
80+
-- = (.||||.) (go src1 tmp1) (go src2 tmp2)
81+
-- (go src3 tmp3) (go src4 tmp4)
82+
tmpA' = A.append tmp1' tmp2'
83+
tmpB' = A.append tmp3' tmp4'
84+
!((srcA'', tmpA''), (srcB'', tmpB''))
85+
= merge_par src1' src2' tmpA' .||. merge_par src3' src4' tmpB'
86+
-- = tuple2 (merge_par src1' src2') tmpA' (merge_par src3' src4') tmpB'
87+
src'' = A.append srcA'' srcB''
88+
!(tmp''', src''') = merge_par tmpA'' tmpB'' src''
89+
in (src''', tmp''') ? lem_toBag_splitMid src
90+
? lem_toBag_splitMid tmp
91+
? lem_toBag_splitMid srcA
92+
? lem_toBag_splitMid srcB
93+
? lem_toBag_splitMid tmpA
94+
? lem_toBag_splitMid tmpB
95+
{-# INLINE cilkSortInplace #-}
7796

7897
{-@ cilkSort' :: y:a
7998
-> { xs:(Array a) | A.size xs > 0 && left xs == 0 && right xs == size xs && y == A.get xs 0 }
@@ -89,6 +108,7 @@ cilkSort' anyVal src =
89108
let !(Ur len, src') = A.size2 src
90109
!src'' = A.allocScratch len anyVal cilkSortInplace src' in
91110
src''
111+
{-# INLINE cilkSort' #-}
92112

93113
-- finally, the top-level merge sort function
94114
{-@ cilkSort :: { xs:(A.Array a) | left xs == 0 && right xs == size xs }
@@ -104,3 +124,4 @@ cilkSort src =
104124
let !(Ur len, src') = A.size2 src in
105125
if len == 0 then src'
106126
else let !(Ur x0, src'') = A.get2 0 src' in cilkSort' x0 src''
127+
{-# INLINABLE cilkSort #-}

0 commit comments

Comments
 (0)