Safe Haskell | Safe-Infered |
---|
Parallel segment descriptors.
See Data.Array.Parallel.Unlifted for how this works.
- data UPSegd = UPSegd {
- upsegd_usegd :: !USegd
- upsegd_dsegd :: Dist ((USegd, Int), Int)
- valid :: UPSegd -> Bool
- mkUPSegd :: Vector Int -> Vector Int -> Int -> UPSegd
- fromUSegd :: USegd -> UPSegd
- empty :: UPSegd
- singleton :: Int -> UPSegd
- fromLengths :: Vector Int -> UPSegd
- length :: UPSegd -> Int
- takeUSegd :: UPSegd -> USegd
- takeDistributed :: UPSegd -> Dist ((USegd, Int), Int)
- takeLengths :: UPSegd -> Vector Int
- takeIndices :: UPSegd -> Vector Int
- takeElements :: UPSegd -> Int
- indicesP :: UPSegd -> Vector Int
- replicateWithP :: Unbox a => UPSegd -> Vector a -> Vector a
- foldWithP :: Unbox a => (a -> a -> a) -> a -> UPSegd -> Vector a -> Vector a
- fold1WithP :: Unbox a => (a -> a -> a) -> UPSegd -> Vector a -> Vector a
- sumWithP :: (Num e, Unbox e) => UPSegd -> Vector e -> Vector e
- foldSegsWithP :: Unbox a => (a -> a -> a) -> (USegd -> Vector a -> Vector a) -> UPSegd -> Vector a -> Vector a
Types
A parallel segment descriptor holds a global (undistributed) segment desciptor, as well as a distributed version. The distributed version describes how to split work on the segmented array over the gang.
UPSegd | |
|
Constructors
:: Vector Int | Length of each segment. |
-> Vector Int | Starting index of each segment. |
-> Int | Total number of elements in the flat array. |
-> UPSegd |
O(1). Construct a new parallel segment descriptor.
singleton :: Int -> UPSegdSource
O(1). Construct a singleton segment descriptor. The single segment covers the given number of elements.
fromLengths :: Vector Int -> UPSegdSource
O(n). Convert an array of segment lengths into a parallel segment descriptor.
The array contains the length of each segment, and we compute the indices from that. Runtime is O(n) in the number of segments.
Projections
takeLengths :: UPSegd -> Vector IntSource
O(1). Yield the lengths of the individual segments.
takeIndices :: UPSegd -> Vector IntSource
O(1). Yield the segment indices.
takeElements :: UPSegd -> IntSource
O(1). Yield the total number of array elements.
takeElements upsegd = sum (takeLengths upsegd)
Indices
indicesP :: UPSegd -> Vector IntSource
O(n). Yield a vector containing indicies that give the position of each member of the flat array in its corresponding segment.
indicesP (fromLengths [5, 2, 3]) = [0,1,2,3,4,0,1,0,1,2]
Replicate
replicateWithP :: Unbox a => UPSegd -> Vector a -> Vector aSource
Copying segmented replication. Each element of the vector is physically copied according to the length of each segment in the segment descriptor.
replicateWith (fromLengths [3, 1, 2]) [5, 6, 7] = [5, 5, 5, 6, 7, 7]
Segmented Folds
foldWithP :: Unbox a => (a -> a -> a) -> a -> UPSegd -> Vector a -> Vector aSource
Fold segments specified by a UPSegd
.
fold1WithP :: Unbox a => (a -> a -> a) -> UPSegd -> Vector a -> Vector aSource
Fold segments specified by a UPSegd
, with a non-empty vector.
sumWithP :: (Num e, Unbox e) => UPSegd -> Vector e -> Vector eSource
Sum up segments specified by a UPSegd
.
foldSegsWithP :: Unbox a => (a -> a -> a) -> (USegd -> Vector a -> Vector a) -> UPSegd -> Vector a -> Vector aSource
Fold the segments specified by a UPSegd
.
This low level function takes a per-element worker and a per-segment worker. It folds all the segments with the per-segment worker, then uses the per-element worker to fixup the partial results when a segment is split across multiple threads.