Safe Haskell | None |
---|

Operations on distributed arrays.

- data Distribution
- balanced :: Distribution
- unbalanced :: Distribution
- lengthD :: Unbox a => Dist (Vector a) -> Dist Int
- splitLenD :: Gang -> Int -> Dist Int
- splitLenIdxD :: Gang -> Int -> Dist (Int, Int)
- splitAsD :: Unbox a => Gang -> Dist Int -> Vector a -> Dist (Vector a)
- splitD :: Unbox a => Gang -> Distribution -> Vector a -> Dist (Vector a)
- joinLengthD :: Unbox a => Gang -> Dist (Vector a) -> Int
- joinD :: Unbox a => Gang -> Distribution -> Dist (Vector a) -> Vector a
- splitJoinD :: (Unbox a, Unbox b) => Gang -> (Dist (Vector a) -> Dist (Vector b)) -> Vector a -> Vector b
- joinDM :: Unbox a => Gang -> Dist (Vector a) -> ST s (MVector s a)
- permuteD :: forall a. Unbox a => Gang -> Dist (Vector a) -> Dist (Vector Int) -> Vector a
- bpermuteD :: Unbox a => Gang -> Vector a -> Dist (Vector Int) -> Dist (Vector a)
- atomicUpdateD :: forall a. Unbox a => Gang -> Dist (Vector a) -> Dist (Vector (Int, a)) -> Vector a
- carryD :: forall a. (Unbox a, DT a) => Gang -> (a -> a -> a) -> a -> Dist Bool -> Dist (Vector a) -> (Dist (Vector a), a)

# Distribution phantom parameter

data Distribution Source

This is a phantom parameter used to record whether a distributed value is balanced evenly among the threads. It's used to signal this property between RULES, but the actual value is never used.

# Array Lengths

lengthD :: Unbox a => Dist (Vector a) -> Dist IntSource

Yield the distributed length of a distributed array.

splitLenD :: Gang -> Int -> Dist IntSource

O(threads).
Distribute an array length over a `Gang`

.
Each thread holds the number of elements it's reponsible for.
If the array length doesn't split evenly among the threads then the first
threads get a few more elements.

splitLenD theGangN4 511 = [128,128,128,127]

splitLenIdxD :: Gang -> Int -> Dist (Int, Int)Source

O(threads).
Distribute an array length over a `Gang`

.
Each thread holds the number of elements it's responsible for,
and the index of the start of its chunk.

splitLenIdxD theGangN4 511 = [(128,0),(128,128),(128,256),(127,384)]

# Splitting and joining

splitAsD :: Unbox a => Gang -> Dist Int -> Vector a -> Dist (Vector a)Source

Distribute an array over a `Gang`

such that each threads gets the given
number of elements.

splitAsD theGangN4 (splitLenD theGangN4 10) [1 2 3 4 5 6 7 8 9 0] = [[1 2 3] [4 5 6] [7 8] [9 0]]

splitD :: Unbox a => Gang -> Distribution -> Vector a -> Dist (Vector a)Source

Distribute an array over a `Gang`

.

NOTE: This is defined in terms of splitD_impl to avoid introducing loops through RULES. Without it, splitJoinD would be a loop breaker.

joinLengthD :: Unbox a => Gang -> Dist (Vector a) -> IntSource

O(threads). Get the overall length of a distributed array. This is implemented by reading the chunk length from each thread, and summing them up.

joinD :: Unbox a => Gang -> Distribution -> Dist (Vector a) -> Vector aSource

Join a distributed array. Join sums up the array lengths of each chunk, allocates a new result array, and copies each chunk into the result.

NOTE: This is defined in terms of joinD_impl to avoid introducing loops through RULES. Without it, splitJoinD would be a loop breaker.

splitJoinD :: (Unbox a, Unbox b) => Gang -> (Dist (Vector a) -> Dist (Vector b)) -> Vector a -> Vector bSource

Split a vector over a gang, run a distributed computation, then join the pieces together again.

joinDM :: Unbox a => Gang -> Dist (Vector a) -> ST s (MVector s a)Source

Join a distributed array, yielding a mutable global array

# Permutations

permuteD :: forall a. Unbox a => Gang -> Dist (Vector a) -> Dist (Vector Int) -> Vector aSource

Permute for distributed arrays.

# Update

atomicUpdateD :: forall a. Unbox a => Gang -> Dist (Vector a) -> Dist (Vector (Int, a)) -> Vector aSource

# Carry

carryD :: forall a. (Unbox a, DT a) => Gang -> (a -> a -> a) -> a -> Dist Bool -> Dist (Vector a) -> (Dist (Vector a), a)Source

Selectively combine the last elements of some chunks with the first elements of others.

NOTE: This runs sequentially and should only be used for testing purposes.

pprp $ splitD theGang unbalanced $ fromList [80, 10, 20, 40, 50, 10 :: Int] DVector lengths: [2,2,1,1] chunks: [[80,10],[20,40],[50],[10]] pprp $ fst $ carryD theGang (+) 0 (mkDPrim $ fromList [True, False, True, False]) (splitD theGang unbalanced $ fromList [80, 10, 20, 40, 50, 10 :: Int]) DVector lengths: [1,2,0,1] chunks: [[80],[30,40],[],[60]]