d447d142c849aa443ad4f6eb87a05ee0395da949

1 {-# LANGUAGE CPP #-}

4 -- | Parallel combinators for unlifted arrays.

6 ( mapUP

7 , filterUP

8 , packUP

10 , zipWithUP

13 where

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

25 mapUP f xs

27 {-# INLINE_UP mapUP #-}

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

32 filterUP f

33 = joinD theGang unbalanced

35 . splitD theGang unbalanced

36 {-# INLINE_UP filterUP #-}

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

40 -- the result.

41 --

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

43 --

45 packUP xs flags

47 {-# INLINE_UP packUP #-}

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

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

52 -- otherwise take it from the second.

53 --

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

55 -- but this is not checked.

56 --

58 combineUP flags xs ys

64 {-# INLINE combineUP #-}

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

68 --

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

70 -- but this is not checked.

71 --

77 $ joinD theGang balanced

78 $ zipWithD theGang go rep

79 $ splitD theGang balanced tags

84 {-# INLINE_UP combine2UP #-}

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

90 zipWithUP f xs ys

91 = splitJoinD theGang

94 {-# INLINE_UP zipWithUP #-}

97 -- | Undirected fold.

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

99 -- standard fold function from the Haskell Prelude.

100 --

101 -- * The worker function must be associative.

102 --

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

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

105 --

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

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

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

109 --

111 foldUP f !z xs

112 = foldD theGang f

115 {-# INLINE_UP foldUP #-}

118 -- | Left fold over an array.

119 --

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

121 --

122 -- * The worker function must be associative.

123 --

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

125 -- see `foldUP` for discussion.

126 --

128 foldlUP f z arr

131 {-# INLINE_UP foldlUP #-}

134 -- | Alias for `foldl1UP`

136 fold1UP = foldl1UP

137 {-# INLINE_UP fold1UP #-}

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

141 -- neural element.

142 --

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

144 --

145 -- * The worker function must be associative.

146 --

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

148 -- see `foldUP` for discussion.

149 --

151 foldl1UP f arr

156 where

162 {-# INLINE_UP foldl1UP #-}

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

166 --

167 -- * The worker function must be associative.

168 --

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

170 -- see `foldUP` for discussion.

171 --

173 scanUP f z

174 = splitJoinD theGang go

178 {-# INLINE_UP scanUP #-}