1 {-# LANGUAGE CPP #-}

4 -- | Parallel combinators for unlifted arrays.

6 ( mapUP

7 , filterUP

8 , packUP

10 , zipWithUP

13 where

24 -- | Apply a worker to all elements of an array.

26 mapUP f xs

27 = splitJoinD theGang

29 {-# INLINE_UP mapUP #-}

32 -- | Keep elements that match the given predicate.

34 filterUP f

35 = joinD theGang unbalanced

37 . splitD theGang unbalanced

38 {-# INLINE_UP filterUP #-}

41 -- | Take elements of an array where a flag value is true, and pack them into

42 -- the result.

43 --

44 -- * The souce and flag arrays must have the same length, but this is not checked.

45 --

47 packUP xs flags

49 {-# INLINE_UP packUP #-}

52 -- | Combine two vectors based on a selector.

53 -- If the selector is true then take the element from the first vector,

54 -- otherwise take it from the second.

55 --

56 -- * The data vectors must have enough elements to satisfy the flag vector,

57 -- but this is not checked.

58 --

60 combineUP flags xs ys

66 {-# INLINE combineUP #-}

69 -- | Combine two vectors based on a selector.

70 --

71 -- * The data vectors must have enough elements to satisfy the selector,

72 -- but this is not checked.

73 --

79 $ joinD theGang balanced

81 $ splitD theGang balanced tags

86 {-# INLINE_UP combine2UP #-}

89 -- | Apply a worker function to correponding elements of two arrays.

92 zipWithUP f xs ys

93 = splitJoinD theGang

96 {-# INLINE_UP zipWithUP #-}

99 -- | Undirected fold.

100 -- Note that this function has more constraints on its parameters than the

101 -- standard fold function from the Haskell Prelude.

102 --

103 -- * The worker function must be associative.

104 --

105 -- * The provided starting element must be neutral with respect to the worker.

106 -- For example 0 is neutral wrt (+) and 1 is neutral wrt (*).

107 --

108 -- We need these constraints so that we can partition the fold across

109 -- several threads. Each thread folds a chunk of the input vector,

110 -- then we fold together all the results in the main thread.

111 --

113 foldUP f !z xs

116 $ splitD theGang unbalanced xs

117 {-# INLINE_UP foldUP #-}

120 -- | Left fold over an array.

121 --

122 -- * If the vector is empty then this returns the provided neural element.

123 --

124 -- * The worker function must be associative.

125 --

126 -- * The provided starting element must be neutral with respect to the worker,

127 -- see `foldUP` for discussion.

128 --

130 foldlUP f z arr

133 {-# INLINE_UP foldlUP #-}

136 -- | Alias for `foldl1UP`

138 fold1UP = foldl1UP

139 {-# INLINE_UP fold1UP #-}

142 -- | Left fold over an array, using the first element of the vector as the

143 -- neural element.

144 --

145 -- * If the vector contains no elements then you'll get a bounds-check error.

146 --

147 -- * The worker function must be associative.

148 --

149 -- * The provided starting element must be neutral with respect to the worker,

150 -- see `foldUP` for discussion.

151 --

153 foldl1UP f arr

158 where

164 {-# INLINE_UP foldl1UP #-}

167 -- | Prefix scan. Similar to fold, but produce an array of the intermediate states.

168 --

169 -- * The worker function must be associative.

170 --

171 -- * The provided starting element must be neutral with respect to the worker,

172 -- see `foldUP` for discussion.

173 --

175 scanUP f z

176 = splitJoinD theGang go

177 where go xs

185 {-# INLINE_UP scanUP #-}