dph-prim-seq (empty) → 0.5.1.1
raw patch · 12 files changed
+1098/−0 lines, 12 filesdep +basedep +dph-basedep +dph-prim-interfacesetup-changed
Dependencies added: base, dph-base, dph-prim-interface, random, vector
Files
- Data/Array/Parallel/Unlifted.hs +97/−0
- Data/Array/Parallel/Unlifted/Sequential/Segmented.hs +27/−0
- Data/Array/Parallel/Unlifted/Sequential/Segmented/Basics.hs +48/−0
- Data/Array/Parallel/Unlifted/Sequential/Segmented/Combinators.hs +56/−0
- Data/Array/Parallel/Unlifted/Sequential/Segmented/Sums.hs +50/−0
- Data/Array/Parallel/Unlifted/Sequential/Segmented/Text.hs +11/−0
- Data/Array/Parallel/Unlifted/Sequential/Segmented/USegd.hs +137/−0
- Data/Array/Parallel/Unlifted/Sequential/USel.hs +122/−0
- Data/Array/Parallel/Unlifted/Sequential/Vector.hs +472/−0
- LICENSE +37/−0
- Setup.hs +3/−0
- dph-prim-seq.cabal +38/−0
+ Data/Array/Parallel/Unlifted.hs view
@@ -0,0 +1,97 @@+{-# LANGUAGE CPP #-}++-- | Primitive sequential combinators that work on flat, unlifted arrays.+--+-- This set of combinators is used when the program is compiled with @-fdph-seq@.+-- When compiling with @-fdph-par@, the ones in the @dph-prim-par package@ are used+-- instead. The @dph-prim-par package@ exports the same names, but all combinators+-- are implemented sequentially.+--+-- The API is defined in @DPH_Header.h@ and @DPH_Interface.h@ to ensure that both+-- @dph-prim-par@ and @dph-prim-seq@ really do export the same symbols.++#include "DPH_Header.h"++import qualified Data.Array.Parallel.Unlifted.Sequential.Vector as V+import Data.Array.Parallel.Unlifted.Sequential.USel+import Data.Array.Parallel.Unlifted.Sequential.Segmented++#include "DPH_Interface.h"++class V.Unbox a => Elt a+type Array = V.Vector+type Segd = USegd+type Sel2 = USel2+type SelRep2 = ()++length = V.length+empty = V.empty+replicate = V.replicate+repeat n _ = V.repeat n+(!:) = (V.!)+extract = V.extract+drop = V.drop+permute = V.permute+bpermute = V.bpermute+mbpermute = V.mbpermute+bpermuteDft = V.bpermuteDft+update = V.update+(+:+) = (V.++)+interleave = V.interleave+pack = V.pack+combine = V.combine+combine2 tags _ = V.combine2ByTag tags+map = V.map+filter = V.filter+zip = V.zip+unzip = V.unzip+fsts = V.fsts+snds = V.snds+zipWith = V.zipWith+fold = V.fold+fold1 = V.fold1+and = V.and+sum = V.sum+scan = V.scan+indexed = V.indexed+enumFromTo = V.enumFromTo+enumFromThenTo = V.enumFromThenTo+enumFromStepLen = V.enumFromStepLen+enumFromStepLenEach = V.enumFromStepLenEach++mkSel2 tags idxs n0 n1 _ = mkUSel2 tags idxs n0 n1+tagsSel2 = tagsUSel2+indicesSel2 = indicesUSel2+elementsSel2_0 = elementsUSel2_0+elementsSel2_1 = elementsUSel2_1+repSel2 _ = ()++mkSelRep2 tags = ()+indicesSelRep2 tags _ = tagsToIndices2 tags+elementsSelRep2_0 tags _ = count tags 0+elementsSelRep2_1 tags _ = count tags 1++replicate_s = replicateSU+replicate_rs = replicateRSU+append_s _ = appendSU+fold_s = foldSU+fold1_s = fold1SU+fold_r = foldlRU+sum_r = sumRU++indices_s = indicesSU++lengthSegd = lengthUSegd+lengthsSegd = lengthsUSegd+indicesSegd = indicesUSegd+elementsSegd = elementsUSegd+mkSegd = mkUSegd+randoms = V.random+randomRs = V.randomR++class V.UIO a => IOElt a+hPut = V.hPut+hGet = V.hGet+toList = V.toList+fromList = V.fromList+
+ Data/Array/Parallel/Unlifted/Sequential/Segmented.hs view
@@ -0,0 +1,27 @@+-- | Interface to operations on segmented unlifted arrays.+module Data.Array.Parallel.Unlifted.Sequential.Segmented (++ replicateSU, replicateRSU, appendSU, indicesSU, indicesSU',++ foldlSU, foldSU, fold1SU,+ foldlRU,+ combineSU,++ -- * Logical operations+ andSU, orSU,++ -- * Arithmetic operations+ sumSU, productSU, maximumSU, minimumSU,+ sumRU,+ USegd,++ -- * Operations on segment descriptors+ lengthUSegd, lengthsUSegd, indicesUSegd, elementsUSegd,+ lengthsToUSegd, mkUSegd+) where+import Data.Array.Parallel.Unlifted.Sequential.Segmented.USegd+import Data.Array.Parallel.Unlifted.Sequential.Segmented.Basics+import Data.Array.Parallel.Unlifted.Sequential.Segmented.Combinators+import Data.Array.Parallel.Unlifted.Sequential.Segmented.Sums+import Data.Array.Parallel.Unlifted.Sequential.Segmented.Text ()+
+ Data/Array/Parallel/Unlifted/Sequential/Segmented/Basics.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE CPP #-}+#include "fusion-phases.h"++-- | Basic segmented operations on unlifted arrays.+module Data.Array.Parallel.Unlifted.Sequential.Segmented.Basics (+ replicateSU, replicateRSU, appendSU, indicesSU, indicesSU'+) where+import Data.Array.Parallel.Stream+import Data.Array.Parallel.Unlifted.Sequential.Vector+import Data.Array.Parallel.Unlifted.Sequential.Segmented.USegd+import qualified Data.Vector.Fusion.Stream as S+++replicateSU :: Unbox a => USegd -> Vector a -> Vector a+{-# INLINE_U replicateSU #-}+replicateSU segd xs = unstream+ (replicateEachS (elementsUSegd segd)+ (S.zip (stream (lengthsUSegd segd)) (stream xs)))+++replicateRSU :: Unbox a => Int -> Vector a -> Vector a+{-# INLINE_U replicateRSU #-}+replicateRSU n xs = unstream+ . replicateEachRS n+ $ stream xs+ ++appendSU :: Unbox a => USegd -> Vector a -> USegd -> Vector a -> Vector a+{-# INLINE_U appendSU #-}+appendSU xd xs yd ys = unstream+ $ appendSS (stream (lengthsUSegd xd))+ (stream xs)+ (stream (lengthsUSegd yd))+ (stream ys)+++indicesSU' :: Int -> USegd -> Vector Int+{-# INLINE_U indicesSU' #-}+indicesSU' i segd = unstream+ . indicesSS (elementsUSegd segd) i+ . stream+ $ lengthsUSegd segd+++indicesSU :: USegd -> Vector Int+{-# INLINE_U indicesSU #-}+indicesSU = indicesSU' 0+
+ Data/Array/Parallel/Unlifted/Sequential/Segmented/Combinators.hs view
@@ -0,0 +1,56 @@+{-# LANGUAGE CPP #-}+#include "fusion-phases.h"++-- | Standard combinators for segmented unlifted arrays.+module Data.Array.Parallel.Unlifted.Sequential.Segmented.Combinators (+ foldlSU, foldSU, foldl1SU, fold1SU, {-scanSU,-} {-scan1SU,-}+ foldlRU,+ combineSU+) where+import Data.Array.Parallel.Stream (+ foldSS, fold1SS, combineSS, foldValuesR )+import Data.Array.Parallel.Unlifted.Sequential.Vector as V+import Data.Array.Parallel.Unlifted.Sequential.Segmented.USegd+import Debug.Trace+++-- | Segmented array reduction proceeding from the left+foldlSU :: (Unbox a, Unbox b) => (b -> a -> b) -> b -> USegd -> Vector a -> Vector b+{-# INLINE_U foldlSU #-}+foldlSU f z segd xs = unstream+ $ foldSS f z (stream (lengthsUSegd segd)) (stream xs)+++-- | Segmented array reduction that requires an associative combination+-- function with its unit+foldSU :: Unbox a => (a -> a -> a) -> a -> USegd -> Vector a -> Vector a+foldSU = foldlSU+++-- | Segmented array reduction from left to right with non-empty subarrays only+foldl1SU :: Unbox a => (a -> a -> a) -> USegd -> Vector a -> Vector a+{-# INLINE_U foldl1SU #-}+foldl1SU f segd xs = unstream+ $ fold1SS f (stream (lengthsUSegd segd)) (stream xs)+++-- | Segmented array reduction with non-empty subarrays and an associative+-- combination function+fold1SU :: Unbox a => (a -> a -> a) -> USegd -> Vector a -> Vector a+fold1SU = foldl1SU+++-- | Merge two segmented arrays according to flag array+combineSU :: Unbox a => Vector Bool -> USegd -> Vector a -> USegd -> Vector a -> Vector a+{-# INLINE_U combineSU #-}+combineSU bs xd xs yd ys = unstream+ $ combineSS (stream bs)+ (stream (lengthsUSegd xd)) (stream xs)+ (stream (lengthsUSegd yd)) (stream ys)+++-- | Regular arrar reduction +foldlRU :: (Unbox a, Unbox b) => (b -> a -> b) -> b -> Int -> Vector a -> Vector b+{-# INLINE_U foldlRU #-}+foldlRU f z segSize = unstream . foldValuesR f z segSize . stream+
+ Data/Array/Parallel/Unlifted/Sequential/Segmented/Sums.hs view
@@ -0,0 +1,50 @@+-- | Sum-like operations on segmented list-like combinators.+module Data.Array.Parallel.Unlifted.Sequential.Segmented.Sums (+ andSU, orSU, sumSU, productSU, maximumSU, minimumSU,+ sumRU+) where+import Data.Array.Parallel.Unlifted.Sequential.Vector as V+import Data.Array.Parallel.Unlifted.Sequential.Segmented.USegd (+ USegd )+import Data.Array.Parallel.Unlifted.Sequential.Segmented.Combinators (+ foldSU, fold1SU, foldlRU)+++-- | Compute the boolean AND of all segments in a segmented array.+andSU :: USegd -> Vector Bool -> Vector Bool+andSU = foldSU (&&) True+++-- | Compute the boolean OR of all segments in a segmented array.+orSU :: USegd -> Vector Bool -> Vector Bool+orSU = foldSU (||) False+++-- | Compute the segmented sum of an array of numerals+sumSU :: (Num e, Unbox e) => USegd -> Vector e -> Vector e+{-# INLINE sumSU #-}+sumSU = foldSU (+) 0+++-- | Compute the segmented product of an array of numerals+productSU :: (Num e, Unbox e) => USegd -> Vector e -> Vector e+{-# INLINE productSU #-}+productSU = foldSU (*) 1+++-- | Determine the maximum element in each subarray+maximumSU :: (Ord e, Unbox e) => USegd -> Vector e -> Vector e+{-# INLINE maximumSU #-}+maximumSU = fold1SU max+++-- | Determine the minimum element in each subarray+minimumSU :: (Ord e, Unbox e) => USegd -> Vector e -> Vector e+{-# INLINE minimumSU #-}+minimumSU = fold1SU min+++-- | Compute the segmented sum of an array of numerals+sumRU :: (Num e, Unbox e) => Int ->Vector e -> Vector e+{-# INLINE sumRU #-}+sumRU = foldlRU (+) 0
+ Data/Array/Parallel/Unlifted/Sequential/Segmented/Text.hs view
@@ -0,0 +1,11 @@+-- | Read\/Show instances for segmented unlifted arrays.+module Data.Array.Parallel.Unlifted.Sequential.Segmented.Text ()+where+import Data.Array.Parallel.Base (+ Read(..), showsApp, readApp)+import Data.Array.Parallel.Unlifted.Sequential.Segmented.USegd (+ USegd, lengthsUSegd )++instance Show USegd where+ showsPrec k = showsApp k "toUSegd" . lengthsUSegd+
+ Data/Array/Parallel/Unlifted/Sequential/Segmented/USegd.hs view
@@ -0,0 +1,137 @@+{-# LANGUAGE CPP #-}+#include "fusion-phases.h"++-- | Segment Descriptors+module Data.Array.Parallel.Unlifted.Sequential.Segmented.USegd (+ -- * Types+ USegd,++ -- * Constructors+ mkUSegd,+ emptyUSegd, singletonUSegd, lengthsToUSegd,++ -- * Projections+ lengthUSegd, lengthsUSegd, indicesUSegd, elementsUSegd, ++ -- * Operations+ sliceUSegd, extractUSegd+) where+import Data.Array.Parallel.Unlifted.Sequential.Vector as V++-- | Segment descriptors represent the structure of nested arrays.+-- For each segment, it stores the length and the starting index in the flat data array.+--+-- Example:+--+-- @+-- flat array data: [1, 2, 3, 4, 5, 6, 7, 8]+-- (segmentation) ---- ------- - ----+-- segd lengths: [2, 3, 1, 2]+-- indices: [0, 2, 5, 6]+-- elements: 8 +-- @+data USegd + = USegd + { usegd_lengths :: !(Vector Int) -- ^ length of each segment+ , usegd_indices :: !(Vector Int) -- ^ starting index of each segment in the flat array+ , usegd_elements :: !Int -- ^ total number of elements in the flat array+ }+++-- Constructors ---------------------------------------------------------------+-- | O(1). Construct a new segment descriptor.+mkUSegd + :: Vector Int -- ^ length of each segment+ -> Vector Int -- ^ starting index of each segment+ -> Int -- ^ total number of elements in the flat array+ -> USegd++{-# INLINE mkUSegd #-}+mkUSegd = USegd+++-- | O(1). Yield an empty segment descriptor, with no elements or segments.+emptyUSegd :: USegd+{-# INLINE emptyUSegd #-}+emptyUSegd = USegd V.empty V.empty 0+++-- | O(1). Yield a singleton segment descriptor.+-- The single segment covers the given number of elements.+singletonUSegd :: Int -> USegd+{-# INLINE singletonUSegd #-}+singletonUSegd n = USegd (V.singleton n) (V.singleton 0) n+++-- | O(n). Convert a length array into a 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.+--+lengthsToUSegd :: Vector Int -> USegd+{-# INLINE lengthsToUSegd #-}+lengthsToUSegd lens+ = USegd lens (V.scanl (+) 0 lens) (V.sum lens)+++-- Projections ----------------------------------------------------------------+-- | O(1). Yield the overall number of segments.+lengthUSegd :: USegd -> Int+{-# INLINE lengthUSegd #-}+lengthUSegd = V.length . usegd_lengths+++-- | O(1). Yield the lengths of the individual segments.+lengthsUSegd :: USegd -> Vector Int+{-# INLINE lengthsUSegd #-}+lengthsUSegd = usegd_lengths+++-- | O(1). Yield the segment indices of a segment descriptor.+indicesUSegd :: USegd -> Vector Int+{-# INLINE indicesUSegd #-}+indicesUSegd = usegd_indices+++-- | O(1). Yield the number of data elements.+elementsUSegd :: USegd -> Int+{-# INLINE elementsUSegd #-}+elementsUSegd = usegd_elements+++-- | O(n). Extract a slice of a segment descriptor, avoiding copying where possible.+--+-- We can share the segment lengths with the original segment descriptor, +-- but still need to recompute the starting indices of each. Hence+-- runtime is O(n) in the number of segments sliced out.+-- +-- NOTE: In the new segment descriptor, the starting index of the first+-- segment will be 0.+sliceUSegd + :: USegd -- ^ source segment descriptor+ -> Int -- ^ index of first segment+ -> Int -- ^ number of segments to slice out+ -> USegd+ +{-# INLINE sliceUSegd #-}+sliceUSegd segd i n+ = lengthsToUSegd $ V.slice (lengthsUSegd segd) i n+++-- | O(n). Extract a slice of a segment descriptor, copying everything.+--+-- In contrast to `sliceUSegd`, this function copies the array of +-- segment lengths as well as recomputing the starting indices of each.+--+-- NOTE: In the new segment descriptor, the starting index of the first+-- segment will be 0.+extractUSegd + :: USegd -- ^ source segment desciptor+ -> Int -- ^ index of the first segment+ -> Int -- ^ number of segments to extract out+ -> USegd++{-# INLINE extractUSegd #-}+extractUSegd segd i n + = lengthsToUSegd $ V.extract (lengthsUSegd segd) i n+
+ Data/Array/Parallel/Unlifted/Sequential/USel.hs view
@@ -0,0 +1,122 @@+-- | A selector is a description of how to perform a `combine` operation.+--+-- Suppose we are evaluating the following expression:+--+-- @combine [F,F,T,F,T,T] [1,2,3] [4,5,6] = [4,5,1,6,2,3]@+--+-- This is difficult to parallelise. For each element in the result, the source +-- array we get this element from depends on the tag values associated with +-- all previous elements.+--+-- However, if we going to perform several combines with the same tag array, we+-- can precompute a selector that tells us where to get each element. The selector+-- contains the original tags, as well as the source index telling us where to get+-- each element for the result array.+--+-- For example:+--+-- @+-- tagsToIndices2 [F,F,T,F,T,T] -- tags+-- = [0,1,0,2,1,2] -- indices+-- @+--+-- This says get the first element from index 0 in the second array, then from index 1 in the second array,+-- then index 0 in the first array ...+-- +-- The selector then consists of both the @tag@ and @indices@ arrays.+--+{-# LANGUAGE CPP #-}++#include "fusion-phases.h"++module Data.Array.Parallel.Unlifted.Sequential.USel (+ -- * Types+ USel2,++ -- * Operations on selectors+ mkUSel2,+ lengthUSel2,+ tagsUSel2, indicesUSel2, elementsUSel2_0, elementsUSel2_1,+ tagsToIndices2+) where+import Data.Array.Parallel.Unlifted.Sequential.Vector as V+import qualified Data.Vector.Fusion.Stream as S+import Data.Vector.Fusion.Stream.Monadic ( Stream(..) )+import Data.Array.Parallel.Base (Tag)+++-- | Abstract selector. +-- Contains both the @tags@ and @indices@ arrays outlined above.+data USel2 + = USel2+ { usel2_tags :: !(Vector Tag)+ , usel2_indices :: !(Vector Int)+ , usel2_elements0 :: !Int -- ^ number of tags with value 0+ , usel2_elements1 :: !Int -- ^ number of tags with value 1+ }+++-- | O(1). Construct a selector.+mkUSel2 :: Vector Tag -- ^ tags array + -> Vector Int -- ^ indices array+ -> Int -- ^ number of elements taken from first array+ -> Int -- ^ number of elements taken from second array+ -> USel2+{-# INLINE mkUSel2 #-}+mkUSel2 = USel2+++-- | O(1). Get the number of elements represented by this selector.+-- This is the length of the array returned by `combine`.+lengthUSel2 :: USel2 -> Int+{-# INLINE lengthUSel2 #-}+lengthUSel2 = V.length . usel2_tags+++-- | O(1). Get the tags array of a selector.+tagsUSel2 :: USel2 -> Vector Tag+{-# INLINE tagsUSel2 #-}+tagsUSel2 = usel2_tags+++-- | O(1). Get the indices array of a selector.+indicesUSel2 :: USel2 -> Vector Int+{-# INLINE indicesUSel2 #-}+indicesUSel2 = usel2_indices+++-- | O(1). Get the number of elements that will be taken from the first array.+elementsUSel2_0 :: USel2 -> Int+{-# INLINE elementsUSel2_0 #-}+elementsUSel2_0 = usel2_elements0+++-- | O(1). Get the number of elements that will be taken from the second array.+elementsUSel2_1 :: USel2 -> Int+{-# INLINE elementsUSel2_1 #-}+elementsUSel2_1 = usel2_elements1+++-- | O(n). Compute the source index for each element of the result array.+tagsToIndices2 :: Vector Tag -> Vector Int+{-# INLINE tagsToIndices2 #-}+tagsToIndices2 tags + = unstream (mapAccumS add (0,0) (stream tags))+ where+ add (i,j) 0 = ((i+1,j),i)+ add (i,j) _ = ((i,j+1),j)+++mapAccumS :: (acc -> a -> (acc,b)) -> acc -> S.Stream a -> S.Stream b+{-# INLINE_STREAM mapAccumS #-}+mapAccumS f acc (Stream step s n)+ = Stream step' (acc,s) n+ where+ {-# INLINE_INNER step' #-}+ step' (acc,s) + = do r <- step s+ case r of+ S.Yield x s' -> let (acc',y) = f acc x+ in return $ S.Yield y (acc',s')+ S.Skip s' -> return $ S.Skip (acc,s')+ S.Done -> return S.Done
+ Data/Array/Parallel/Unlifted/Sequential/Vector.hs view
@@ -0,0 +1,472 @@+{-# LANGUAGE ScopedTypeVariables, BangPatterns, CPP #-}++#include "fusion-phases.h"++-- | Wrappers for primitives defined in @Data.Vector@+module Data.Array.Parallel.Unlifted.Sequential.Vector (++ -- * Array classes+ Unbox,++ -- * Array types+ Vector, MVector,++ -- * Streaming+ stream, unstream,++ -- * Basic operations+ length, null, empty, singleton, cons, units,+ replicate,+ -- replicateEachU,+ (!), (++),+ interleave, indexed, repeat, repeatS,++ -- * Subarrays+ slice, extract,+ tail,+ take, drop, splitAt,++ -- * Permutations+ permute, bpermute, mbpermute, bpermuteDft, reverse, update,+++ -- * Higher-order operations+ map, zipWith, zipWith3,+ filter, pack, + combine, combine2ByTag,+ foldl, foldl1, foldl1Maybe,+ fold, fold1, fold1Maybe,+ scanl, scanl1,+ scan, scan1,+ scanRes,++ -- * Searching+ elem, notElem,++ -- * Logical operations+ and, or, any, all,++ -- * Arithmetic operations+ sum, product,+ maximum, minimum,+ maximumBy, minimumBy,+ maxIndex, minIndex,+ maxIndexBy, minIndexBy,++ -- * Arrays of pairs+ zip, unzip, fsts, snds,++ -- * Enumerations+ enumFromTo, enumFromThenTo, enumFromStepLen, enumFromToEach, enumFromStepLenEach,++ -- * Searching+ find, findIndex,++ -- * Conversions to\/from lists+ toList, fromList,++ -- * Random arrays+ random, randomR,++ -- * Mutating operations+ new, copy,++ -- * Mutable vectors+ newM, unsafeFreeze, M.write, M.read, mpermute, mupdate,+ mdrop, mslice,++ -- * I\/O+ UIO(..)++) where++import Data.Array.Parallel.Stream+import Data.Array.Parallel.Base ( Tag, checkEq, ST )++import Data.Vector.Unboxed hiding ( slice, zip, unzip, foldl, foldl1, scanl, scanl1 )+import qualified Data.Vector.Unboxed as V+import qualified Data.Vector.Unboxed.Mutable as M+import qualified Data.Vector.Unboxed.Base as VBase+import Data.Vector.Generic ( stream, unstream )+import qualified Data.Vector.Generic as G+import qualified Data.Vector.Generic.Mutable as MG+import qualified Data.Vector.Storable as Storable+import qualified Data.Vector.Storable.Mutable as MStorable+import qualified Data.Vector.Generic.New as New+import qualified Data.Vector.Fusion.Stream as S+import Data.Vector.Fusion.Stream.Monadic ( Stream(..), Step(..) )+import Data.Vector.Fusion.Stream.Size ( Size(..) )+import Prelude hiding ( length, null,+ replicate, (++), repeat,+ tail, take, drop, splitAt,+ reverse,+ map, zipWith, zipWith3, filter,+ foldl, foldl1, scanl, scanl1,+ elem, notElem,+ and, or, any, all,+ sum, product,+ maximum, minimum,+ zip, unzip,+ enumFromTo, enumFromThenTo )+import qualified Prelude+import qualified System.Random as R+import Foreign hiding ( new )+import System.IO++here s = "Data.Array.Parallel.Unlifted.Sequential.Flat." Prelude.++ s+++new :: Unbox a => Int -> (forall s. MVector s a -> ST s ()) -> Vector a+{-# INLINE new #-}+new n p = V.create (do+ v <- M.new n+ p v+ return v)+++newM :: Unbox a => Int -> ST s (MVector s a)+{-# INLINE newM #-}+newM = M.new+++-- | Yield an array of units +units :: Int -> Vector ()+{-# INLINE units #-}+units n = replicate n ()+ ++-- | Interleave the elements of two arrays+interleave :: Unbox e => Vector e -> Vector e -> Vector e+{-# INLINE_U interleave #-}+interleave xs ys = unstream (interleaveS (stream xs) (stream ys))+++-- | Repeat an array @n@ times+repeat :: Unbox e => Int -> Vector e -> Vector e+{-# INLINE_U repeat #-}+repeat n xs = unstream (repeatS n xs)+++repeatS :: Unbox e => Int -> Vector e -> S.Stream e+{-# INLINE_STREAM repeatS #-}+repeatS k !xs = Stream next (0,k) (Exact (k*n))+ where+ !n = length xs++ {-# INLINE next #-}+ next (i,0) = return Done+ next (i,k) | i == n = return $ Skip (0,k-1)+ | otherwise = return $ Yield (unsafeIndex xs i) (i+1,k)+++slice :: Unbox a => Vector a -> Int -> Int -> Vector a+{-# INLINE_U slice #-}+slice xs i n = V.slice i n xs+++extract :: Unbox a => Vector a -> Int -> Int -> Vector a+{-# INLINE_U extract #-}+extract xs i n = force (V.slice i n xs)+++mupdate :: Unbox e => MVector s e -> Vector (Int,e) -> ST s ()+{-# INLINE_U mupdate #-}+mupdate marr xs = MG.update marr (stream xs)+++mpermute :: Unbox e => MVector s e -> Vector e -> Vector Int -> ST s ()+{-# INLINE_U mpermute #-}+mpermute marr xs is = MG.update marr (stream (zip is xs))+++permute :: Unbox e => Vector e -> Vector Int -> Vector e+{-# INLINE_U permute #-}+permute xs is = create (do+ v <- M.new (length xs)+ mpermute v xs is+ return v)+++bpermute :: Unbox e => Vector e -> Vector Int -> Vector e+{-# INLINE_U bpermute #-}+bpermute = backpermute+++mbpermute :: (Unbox e, Unbox d) => (e -> d) -> Vector e -> Vector Int -> Vector d+{-# INLINE_STREAM mbpermute #-}+mbpermute f es is = unstream (mbpermuteS f es (stream is))+++bpermuteS :: Unbox e => Vector e -> S.Stream Int -> S.Stream e+{-# INLINE_STREAM bpermuteS #-}+bpermuteS !a s = S.map (a!) s+++mbpermuteS:: Unbox e => (e -> d) -> Vector e -> S.Stream Int -> S.Stream d+{-# INLINE_STREAM mbpermuteS #-}+mbpermuteS f !a = S.map (f . (a!))+++-- | Default back permute+--+-- * The values of the index-value pairs are written into the position in the+-- result array that is indicated by the corresponding index.+--+-- * All positions not covered by the index-value pairs will have the value+-- determined by the initialiser function for that index position.+--+bpermuteDft :: Unbox e+ => Int -- ^ length of result array+ -> (Int -> e) -- ^ initialiser function+ -> Vector (Int,e) -- ^ index-value pairs+ -> Vector e+{-# INLINE_U bpermuteDft #-}+bpermuteDft n init = update (map init (enumFromN 0 n))+++-- | Extract all elements from an array according to a given flag array+pack:: Unbox e => Vector e -> Vector Bool -> Vector e+{-# INLINE_U pack #-}+pack xs = map fst . filter snd . zip xs+++combine :: Unbox a+ => Vector Bool -> Vector a -> Vector a -> Vector a+{-# INLINE combine #-}+combine bs = combine2ByTag (map (\b -> if b then 0 else 1) bs)+++combine2ByTag :: Unbox a => Vector Tag -> Vector a -> Vector a -> Vector a+{-# INLINE_U combine2ByTag #-}+combine2ByTag ts xs ys+ = checkEq (here "combine2ByTag")+ ("tags length /= sum of args length")+ (length ts) (length xs + length ys)+ $ unstream (combine2ByTagS (stream ts) (stream xs) (stream ys))+++-- | Array reduction proceeding from the left+foldl :: Unbox a => (b -> a -> b) -> b -> Vector a -> b+{-# INLINE_U foldl #-}+foldl = foldl'+++-- | Array reduction proceeding from the left for non-empty arrays+foldl1 :: Unbox a => (a -> a -> a) -> Vector a -> a+{-# INLINE_U foldl1 #-}+foldl1 = foldl1'++-- | Array reduction that requires an associative combination function with its+-- unit+fold :: Unbox a => (a -> a -> a) -> a -> Vector a -> a+{-# INLINE_U fold #-}+fold = foldl+++-- | Reduction of a non-empty array which requires an associative combination+-- function+fold1 :: Unbox a => (a -> a -> a) -> Vector a -> a+{-# INLINE_U fold1 #-}+fold1 = foldl1+++foldl1Maybe :: Unbox a => (a -> a -> a) -> Vector a -> Maybe a+{-# INLINE_U foldl1Maybe #-}+foldl1Maybe f xs = foldl' join Nothing xs+ where+ {-# INLINE join #-}+ join Nothing y = Just $! y+ join (Just x) y = Just $! f x y+++fold1Maybe :: Unbox a => (a -> a -> a) -> Vector a -> Maybe a+{-# INLINE_U fold1Maybe #-}+fold1Maybe = foldl1Maybe++-- | Prefix scan proceedings from left to right+scanl :: (Unbox a, Unbox b) => (b -> a -> b) -> b -> Vector a -> Vector b+{-# INLINE_U scanl #-}+scanl = prescanl'+++-- | Prefix scan of a non-empty array proceeding from left to right+scanl1 :: Unbox a => (a -> a -> a) -> Vector a -> Vector a+{-# INLINE_U scanl1 #-}+scanl1 = scanl1'+++-- | Prefix scan proceeding from left to right that needs an associative+-- combination function with its unit+scan :: Unbox a => (a -> a -> a) -> a -> Vector a -> Vector a+{-# INLINE_U scan #-}+scan = scanl+++-- | Prefix scan of a non-empty array proceeding from left to right that needs+-- an associative combination function+scan1 :: Unbox a => (a -> a -> a) -> Vector a -> Vector a+{-# INLINE_U scan1 #-}+scan1 = scanl1+++scanRes :: Unbox a => (a -> a -> a) -> a -> Vector a -> (Vector a,a)+{-# INLINE_U scanRes #-}+scanRes f z xs = let ys = scanl' f z xs+ in+ (unsafeInit ys, unsafeLast ys)+++fsts :: (Unbox a, Unbox b) => Vector (a,b) -> Vector a+{-# INLINE_STREAM fsts #-}+fsts (VBase.V_2 _ xs ys) = xs+++snds :: (Unbox a, Unbox b) => Vector (a,b) -> Vector b+{-# INLINE_STREAM snds #-}+snds (VBase.V_2 _ xs ys) = ys+++zip :: (Unbox a, Unbox b) => Vector a -> Vector b -> Vector (a,b)+{-# INLINE_STREAM zip #-}+zip !xs !ys = V.zip xs ys+++unzip :: (Unbox a, Unbox b) => Vector (a,b) -> (Vector a, Vector b)+{-# INLINE_STREAM unzip #-}+unzip ps = V.unzip ps++{-# RULES++"fsts/new/unstream [dph-prim-seq]" forall xs.+ fsts (G.new (New.unstream xs)) = V.map fst (G.new (New.unstream xs))++"snds/new/unstream [dph-prim-seq]" forall xs.+ snds (G.new (New.unstream xs)) = V.map snd (G.new (New.unstream xs))++"stream/zip [dph-prim-seq]" forall xs ys.+ G.stream (zip xs ys) = S.zip (G.stream xs) (G.stream ys)++ #-}+++enumFromStepLen :: Int -> Int -> Int -> Vector Int+{-# INLINE_U enumFromStepLen #-}+enumFromStepLen = enumFromStepN+++enumFromToEach :: Int -> Vector (Int,Int) -> Vector Int+{-# INLINE_U enumFromToEach #-}+enumFromToEach n = unstream . enumFromToEachS n . stream+++enumFromStepLenEach :: Int -> Vector Int -> Vector Int -> Vector Int -> Vector Int+{-# INLINE_U enumFromStepLenEach #-}+enumFromStepLenEach len starts steps lens+ = unstream $ enumFromStepLenEachS len $ stream $ V.zip3 starts steps lens+++random :: (Unbox a, R.Random a, R.RandomGen g) => Int -> g -> Vector a+{-# INLINE_U random #-}+random n = unstream . randomS n+++randomR :: (Unbox a, R.Random a, R.RandomGen g) => Int -> (a,a) -> g -> Vector a+{-# INLINE_U randomR #-}+randomR n r = unstream . randomRS n r+++randomS :: (R.RandomGen g, R.Random a) => Int -> g -> S.Stream a+{-# INLINE_STREAM randomS #-}+randomS n g = Stream step (g,n) (Exact n)+ where+ {-# INLINE step #-}+ step (g,0) = return Done+ step (g,n) = let (x,g') = R.random g+ in return $ Yield x (g',n-1)+++randomRS :: (R.RandomGen g, R.Random a) => Int -> (a,a) -> g -> S.Stream a+{-# INLINE_STREAM randomRS #-}+randomRS n r g = Stream step (g,n) (Exact n)+ where+ {-# INLINE step #-}+ step (g,0) = return Done+ step (g,n) = let (x,g') = R.randomR r g+ in return $ Yield x (g',n-1)+++mdrop :: Unbox a => Int -> MVector s a -> MVector s a+{-# INLINE mdrop #-}+mdrop = M.drop+++mslice :: Unbox a => Int -> Int -> MVector s a -> MVector s a+{-# INLINE mslice #-}+mslice = M.slice+++hGetStorable :: forall a. Storable a => Handle -> IO (Storable.Vector a)+hGetStorable h =+ alloca $ \iptr ->+ do+ hGetBuf h iptr (sizeOf (undefined :: Int))+ n <- peek iptr+ v <- MStorable.unsafeNew n+ let bytes = sizeOf (undefined :: a) * MStorable.length v+ r <- MStorable.unsafeWith v $ \ptr -> hGetBuf h ptr bytes+ Storable.unsafeFreeze (MStorable.take r v)+++hPutStorable :: forall a. Storable a => Handle -> Storable.Vector a -> IO ()+hPutStorable h xs =+ alloca $ \iptr ->+ do+ poke iptr n + hPutBuf h iptr (sizeOf n)+ Storable.unsafeWith xs $ \ptr ->+ do+ hPutBuf h ptr (sizeOf (undefined :: a) * n)+ return ()+ where+ !n = Storable.length xs++class Unbox a => UIO a where+ hPut :: Handle -> Vector a -> IO ()+ hGet :: Handle -> IO (Vector a)+++primPut :: (Unbox a, Storable a) => Handle -> Vector a -> IO ()+{-# INLINE primPut #-}+primPut h = hPutStorable h . Storable.convert+++primGet :: (Unbox a, Storable a) => Handle -> IO (Vector a)+{-# INLINE primGet #-}+primGet = fmap convert . hGetStorable+++instance UIO Int where+ {-# INLINE hPut #-}+ hPut = primPut+ {-# INLINE hGet #-}+ hGet = primGet+++instance UIO Double where+ {-# INLINE hPut #-}+ hPut = primPut+ {-# INLINE hGet #-}+ hGet = primGet+++instance (UIO a, UIO b) => UIO (a,b) where+ {-# INLINE hPut #-}+ hPut h xs = case V.unzip xs of+ (ys,zs) -> do hPut h ys+ hPut h zs++ {-# INLINE hGet #-}+ hGet h = do xs <- hGet h+ ys <- hGet h+ return (V.zip xs ys)+
+ LICENSE view
@@ -0,0 +1,37 @@+Copyright (c) 2001-2011, The DPH Team+All rights reserved.++The DPH Team is:+ Manuel M T Chakravarty+ Gabriele Keller+ Roman Leshchinskiy+ Ben Lippmeier+ George Roldugin++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++- Redistributions of source code must retain the above copyright notice,+this list of conditions and the following disclaimer.+ +- Redistributions in binary form must reproduce the above copyright notice,+this list of conditions and the following disclaimer in the documentation+and/or other materials provided with the distribution.+ +- Neither name of the University nor the names of its contributors may be+used to endorse or promote products derived from this software without+specific prior written permission. ++THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF+GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE+UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH+DAMAGE.+
+ Setup.hs view
@@ -0,0 +1,3 @@+import Distribution.Simple+main = defaultMain+
+ dph-prim-seq.cabal view
@@ -0,0 +1,38 @@+Name: dph-prim-seq+Version: 0.5.1.1+License: BSD3+License-File: LICENSE+Author: The DPH Team+Maintainer: Ben Lippmeier <benl@cse.unsw.edu.au>+Homepage: http://www.haskell.org/haskellwiki/GHC/Data_Parallel_Haskell+Category: Data Structures+Synopsis: Sequential Primitives for Data-Parallel Haskell.++Cabal-Version: >= 1.6+Build-Type: Simple++Library+ Exposed-Modules:+ Data.Array.Parallel.Unlifted.Sequential.Segmented+ Data.Array.Parallel.Unlifted.Sequential.Segmented.USegd+ Data.Array.Parallel.Unlifted.Sequential.Vector+ Data.Array.Parallel.Unlifted.Sequential.USel+ Data.Array.Parallel.Unlifted+ Other-Modules:+ Data.Array.Parallel.Unlifted.Sequential.Segmented.Basics+ Data.Array.Parallel.Unlifted.Sequential.Segmented.Combinators+ Data.Array.Parallel.Unlifted.Sequential.Segmented.Sums+ Data.Array.Parallel.Unlifted.Sequential.Segmented.Text++ Exposed: False++ Extensions: TypeFamilies, GADTs, RankNTypes,+ BangPatterns, MagicHash, UnboxedTuples, TypeOperators+ GHC-Options: -Odph -funbox-strict-fields -fcpr-off++ Build-Depends: + base == 4.4.*,+ random == 1.0.*,+ vector == 0.7.*,+ dph-base == 0.5.*,+ dph-prim-interface == 0.5.*