packages feed

dph-lifted-base (empty) → 0.6.0.1

raw patch · 7 files changed

+881/−0 lines, 7 filesdep +arraydep +basedep +containerssetup-changed

Dependencies added: array, base, containers, dph-base, dph-prim-par, ghc, pretty, random, template-haskell, vector

Files

+ Data/Array/Parallel/PArr.hs view
@@ -0,0 +1,91 @@+{-# OPTIONS_GHC -funbox-strict-fields #-}+{-# OPTIONS_HADDOCK hide #-}++--   NOTE NOTE NOTE+--   This file is IDENTICAL to the one in dph-lifted-boxed.+--   If you update one then update the other as well.++-- | Unvectorised functions that work directly on parallel arrays of [::] type.+--   These are used internally in the DPH library, but the user never sees them.+--   Only vectorised functions are visible in the DPH client programs.+--+module Data.Array.Parallel.PArr +        ( PArr+        , emptyPArr+        , replicatePArr+        , singletonPArr+        , indexPArr+        , headPArr+        , lengthPArr)+where+import GHC.ST+import GHC.Base+import GHC.PArr++-- | Construct an empty array, with no elements.+emptyPArr :: PArr a+emptyPArr = replicatePArr 0 undefined+{-# NOINLINE emptyPArr #-}+++-- | Construct an array with a single element.+singletonPArr :: a -> PArr a+singletonPArr e = replicatePArr 1 e+{-# NOINLINE singletonPArr #-}+++-- | Construct an array by replicating the given element some number of times.+replicatePArr :: Int -> a -> PArr a+replicatePArr n e  + = runST (do+         marr# <- newArray n e+         mkPArr n marr#)+{-# NOINLINE replicatePArr #-}+++-- | Take the length of an array.+lengthPArr :: PArr a -> Int+lengthPArr (PArr n _) = n+{-# NOINLINE lengthPArr #-}+++-- | Lookup a single element from the source array.+indexPArr :: PArr e -> Int -> e+indexPArr (PArr n arr#) i@(I# i#)+  | i >= 0 && i < n +  = case indexArray# arr# i# of (# e #) -> e++  | otherwise+  = error $  "indexPArr: out of bounds parallel array index; " +          ++ "idx = " ++ show i ++ ", arr len = "+          ++ show n+{-# NOINLINE indexPArr #-}+++-- | Take the first element of the source array, +--   or `error` if there isn't one.+headPArr :: PArr a -> a+headPArr arr = indexPArr arr 0+{-# NOINLINE headPArr #-}+++-------------------------------------------------------------------------------+-- | Internally used mutable boxed arrays+data MPArr s e = MPArr !Int (MutableArray# s e)+++-- | Allocate a new mutable array that is pre-initialised with a given value+newArray :: Int -> e -> ST s (MPArr s e)+newArray n@(I# n#) e  = ST $ \s1# ->+  case newArray# n# e s1# of { (# s2#, marr# #) ->+  (# s2#, MPArr n marr# #)}+{-# INLINE newArray #-}+++-- | Convert a mutable array into the external parallel array representation+mkPArr :: Int -> MPArr s e -> ST s (PArr e)+mkPArr n (MPArr _ marr#)  = ST $ \s1# ->+  case unsafeFreezeArray# marr# s1#   of { (# s2#, arr# #) ->+  (# s2#, PArr n arr# #) }+{-# INLINE mkPArr #-}+
+ Data/Array/Parallel/PArray.hs view
@@ -0,0 +1,400 @@++-- | Reference implementation of operators on unvectorised parallel arrays.+--+--   * In this module we just used boxed vectors as the array representation. +--     This won't be fast, but it means we can write the operators without+--     needing type class dictionaries such as PA. This makes them+--     much easier to use as reference code.+--+--   * The operators should also all do bounds checks, sanity checks, and +--     give nice error messages if something is wrong. The ideas is that+--     this code can be run side-by-side production code during debugging.+---+--   TODO: check lengths properly in functions like zip, extracts+--+module Data.Array.Parallel.PArray+        ( PArray+        , valid+        , nf+        +        -- * Constructors+        , empty+        , singleton,    singletonl+        , replicate,    replicatel,     replicates,     replicates'+        , append,       appendl+        , concat,       concatl+        , unconcat+        , nestUSegd+        +        -- * Projections+        , length,       lengthl+        , index,        indexl+        , extract,      extracts,       extracts'+        , slice,        slicel+        , takeUSegd+        +        -- * Pack and Combine+        , pack,         packl+        , packByTag+        , combine2+        +        -- * Enumerations+        , enumFromTo,   enumFromTol+        +        -- * Tuples+        , zip,          zipl+        , unzip,        unzipl+        +        -- * Conversions+        , fromVector,   toVector+        , fromList,     toList+        , fromUArray,   toUArray+        , fromUArray2)+where+import Data.Array.Parallel.Base                 (Tag)+import Data.Vector                              (Vector)+import qualified Data.Array.Parallel.Unlifted   as U+import qualified Data.Vector                    as V+import qualified Prelude                        as P+import Control.Monad+import GHC.Exts+import Prelude hiding+        ( replicate, length, concat+        , enumFromTo+        , zip, unzip)++-------------------------------------------------------------------------------+here :: String -> String+here str   = "Data.Array.Parallel.PArray." ++ str++die :: String -> String -> a+die fn str = error (here $ fn ++ " " ++ str)++-- Array Type -----------------------------------------------------------------+type PArray a+        = Vector a+        +-- | Lift a unary array operator.+lift1   :: (a -> b) -> PArray a -> PArray b+lift1 f vec+        = V.map f vec+++-- | Lift a binary array operator.+lift2   :: (a -> b -> c) -> PArray a -> PArray b -> PArray c+lift2 f vec1 vec2+        | V.length vec1 /= V.length vec2+        = die "lift2" "length mismatch"+ +        | otherwise+        = V.zipWith f vec1 vec2+++-- | Lift a trinary array operator+lift3   :: (a -> b -> c -> d) -> PArray a -> PArray b -> PArray c -> PArray d+lift3 f vec1 vec2 vec3+        |   V.length vec1 /= V.length vec2+         || V.length vec1 /= V.length vec3+        = die "lift3" "length mismatch"+ +        | otherwise+        = V.zipWith3 f vec1 vec2 vec3+++-- Basics ---------------------------------------------------------------------+-- | Check that an array has a valid internal representation.+valid :: PArray a -> Bool+valid _ = True++-- | Force an array to normal form.+nf :: PArray a -> ()+nf _    = ()+++-- Constructors ----------------------------------------------------------------+-- | O(1). An empty array.+empty :: PArray a+empty           = V.empty+++-- | O(1). Produce an array containing a single element.+singleton :: a -> PArray a+singleton       = V.singleton+++-- | O(n). Produce an array of singleton arrays.+singletonl :: PArray a -> PArray (PArray a)+singletonl      = lift1 singleton+++-- | O(n). Define an array of the given size, that maps all elements to the same value.+replicate :: Int -> a -> PArray a+replicate       = V.replicate+++-- | O(sum lengths). Lifted replicate.+replicatel :: PArray Int -> PArray a -> PArray (PArray a)+replicatel      = lift2 replicate+++-- | O(sum lengths). Segmented replicate.+replicates :: U.Segd -> PArray a -> PArray a+replicates segd vec+        | V.length vec /= U.lengthSegd segd+        = die "replicates" $ unlines+                [ "segd length mismatch"+                , "  segd length  = " ++ (show $ U.lengthSegd segd)+                , "  array length = " ++ (show $ V.length vec)]++        | otherwise+        = join +        $ V.zipWith V.replicate+                (V.convert $ U.lengthsSegd segd)+                vec+++-- | O(sum lengths). Wrapper for segmented replicate that takes replication counts+--  and uses them to build the `U.Segd`.+replicates' :: PArray Int -> PArray a -> PArray a+replicates' reps arr+        = replicates (U.lengthsToSegd $ V.convert $ reps) arr+++-- | Append two arrays.+append :: PArray a -> PArray a -> PArray a+append          = (V.++)+++-- | Lifted append.+appendl :: PArray (PArray a) -> PArray (PArray a) -> PArray (PArray a)+appendl         = lift2 append+++-- | Concatenation+concat :: PArray (PArray a) -> PArray a+concat          = join+++-- | Lifted concatenation.+concatl :: PArray (PArray (PArray a)) -> PArray (PArray a)+concatl         = lift1 concat+++-- | Impose a nesting structure on a flat array+unconcat :: PArray (PArray a) -> PArray b -> PArray (PArray b)+unconcat arr1 arr2+        = nestUSegd (takeUSegd arr1) arr2+++-- | Create a nested array from a segment descriptor and some flat data.+--   The segment descriptor must represent as many elements as present+--   in the flat data array, else `error`+nestUSegd :: U.Segd -> PArray a -> PArray (PArray a)+nestUSegd segd vec+        | U.elementsSegd segd     == V.length vec +        = V.zipWith+                (\start len -> V.slice start len vec)+                (V.convert $ U.indicesSegd segd)+                (V.convert $ U.lengthsSegd segd)++        | otherwise+        = error $ unlines+                [ "Data.Array.Parallel.PArray.nestSegd: number of elements defined by "+                        ++ "segment descriptor and data array do not match"+                , " length of segment desciptor = " ++ (show $ U.elementsSegd segd)+                , " length of data array        = " ++ (show $ V.length vec)]+{-# NOINLINE nestUSegd #-}+++-- Projections ----------------------------------------------------------------+-- | Take the length of an array+length :: PArray a -> Int+length          = V.length+++-- | Take the length of some arrays.+lengthl :: PArray (PArray a) -> PArray Int+lengthl         = lift1 length+++-- | Lookup a single element from the source array.+index :: PArray a -> Int -> a+index           = (V.!)+++-- | Lookup a several elements from several source arrays.+indexl :: PArray (PArray a) -> PArray Int -> PArray a+indexl          = lift2 index+++-- | Extract a range of elements from an array.+extract :: PArray a -> Int -> Int -> PArray a+extract vec start len+        = V.slice start len vec+++-- | Segmented extract.+extracts :: Vector (PArray a) -> U.SSegd -> PArray a+extracts arrs ssegd+        = join+        $ V.zipWith3+                (\src start len -> extract (arrs V.! src) start len)+                (V.convert $ U.sourcesOfSSegd ssegd)+                (V.convert $ U.startsOfSSegd  ssegd)+                (V.convert $ U.lengthsOfSSegd ssegd)+++-- | Wrapper for `extracts` that takes arrays of sources, starts and lengths of+--   the segments, and uses these to build the `U.SSegd`.+extracts' +        :: Vector (PArray a) +        -> PArray Int           -- ^ id of source array for each segment.+        -> PArray Int           -- ^ starting index of each segment in its source array.+        -> PArray Int           -- ^ length of each segment.+        -> PArray a+extracts' arrs sources starts lengths+ = let  segd    = U.lengthsToSegd $ V.convert lengths+        ssegd   = U.mkSSegd +                        (V.convert $ starts)+                        (V.convert $ sources)+                        segd+   in   extracts arrs ssegd+++-- | Extract a range of elements from an arrary.+--   Like `extract` but with the parameters in a different order.+slice :: Int -> Int -> PArray a -> PArray a+slice start len arr+        = extract arr start len+++-- | Extract some slices from some arrays.+--   The arrays of starting indices and lengths must themselves+--   have the same length.+slicel :: PArray Int -> PArray Int -> PArray (PArray a) -> PArray (PArray a)+slicel  = lift3 slice+++-- | Take the segment descriptor from a nested array. This can cause index space+--   overflow if the number of elements in the result does not can not be+--   represented by a single machine word.+takeUSegd :: PArray (PArray a) -> U.Segd+takeUSegd vec+        = U.lengthsToSegd +        $ V.convert+        $ V.map length vec+        ++-- Pack and Combine -----------------------------------------------------------+-- | Select the elements of an array that have their tag set to True.+pack    :: PArray a -> PArray Bool -> PArray a+pack xs bs+        | V.length xs /= V.length bs+        = die "pack" $ unlines+                [ "array length mismatch"+                , "  data  length = " ++ (show $ V.length xs)+                , "  flags length = " ++ (show $ V.length bs) ]++        | otherwise+        = V.ifilter (\i _ -> bs V.! i) xs+++-- | Lifted pack.+packl :: PArray (PArray a) -> PArray (PArray Bool) -> PArray (PArray a)+packl   = lift2 pack+++-- | Filter an array based on some tags.+packByTag :: PArray a -> U.Array Tag -> Tag -> PArray a+packByTag xs tags tag+        | V.length xs /= U.length tags+        = die "packByTag" $ unlines+                [ "array length mismatch"+                , "  data  length = " ++ (show $ V.length xs)+                , "  flags length = " ++ (show $ U.length tags) ]++        | otherwise+        = V.ifilter (\i _ -> U.index (here "packByTag") tags i == tag) xs+++-- | Combine two arrays based on a selector.+combine2 :: U.Sel2 -> PArray a -> PArray a -> PArray a+combine2 tags vec1 vec2+ = let  go [] [] []                     = []+        go (0 : bs) (x : xs) ys         = x : go bs xs ys+        go (1 : bs) xs       (y : ys)   = y : go bs xs ys+        go _ _ _ = error "Data.Array.Parallel.PArray.combine: length mismatch"+ +   in   V.fromList+                $ go    (V.toList $ V.convert $ U.tagsSel2 tags)+                        (V.toList vec1)+                        (V.toList vec2)+++-- Enumerations ---------------------------------------------------------------+-- | Construct a range of integers+enumFromTo :: Int -> Int -> PArray Int+enumFromTo      = V.enumFromTo+++-- | Lifted enumeration+enumFromTol :: PArray Int -> PArray Int -> PArray (PArray Int)+enumFromTol     = lift2 enumFromTo+++-- Tuples ---------------------------------------------------------------------+-- | O(n). Zip a pair of arrays into an array of pairs.+zip     :: PArray a -> PArray b -> PArray (a, b)+zip     = V.zip+++-- | Lifted zip+zipl    :: PArray (PArray a) -> PArray (PArray b) -> PArray (PArray (a, b))+zipl    = lift2 zip+++-- | O(n). Unzip an array of pairs into a pair of arrays.+unzip   :: PArray (a, b) -> (PArray a, PArray b)+unzip   = V.unzip+++-- | Lifted unzip+unzipl  :: PArray (PArray (a, b)) -> PArray (PArray a, PArray b)+unzipl  = lift1 unzip+++-- Conversions ----------------------------------------------------------------+-- | Convert a `Vector` to a `PArray`+fromVector :: Vector a -> PArray a+fromVector = id+++-- | Convert a `PArray` to a `Vector`        +toVector   :: PArray a -> Vector a+toVector   = id++-- | Convert a list to a `PArray`.+fromList   :: [a] -> PArray a+fromList   = V.fromList++-- | Convert a `PArray` to a list.+toList     :: PArray a -> [a]+toList     = V.toList+++-- | Convert a `U.Array` to a `PArray`+fromUArray :: U.Elt a => U.Array a -> PArray a+fromUArray  = V.convert+++-- | Convert a `PArray` to a `U.Array`+toUArray   :: U.Elt a => PArray a -> U.Array a+toUArray    = V.convert+++-- | Convert a `U.Array` of tuples to a `PArray`+fromUArray2+        :: (U.Elt a, U.Elt b)+        => U.Array (a, b) -> PArray (a, b)+        +fromUArray2  = V.convert
+ Data/Array/Parallel/PArray/Reference.hs view
@@ -0,0 +1,170 @@+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS -fno-warn-missing-signatures #-}+-- | During testing, we compare the output of each invocation of the lifted+--   combinators in "Data.Array.Parallel.PArray" with the reference implementations. +--+--   This module helps convert the to and from the array representation+--   used by the reference implementation.++--   TODO: we could use this to trace the lengths of the vectors being used, +--         as well as the types that each opeartor is being called at.+--+module Data.Array.Parallel.PArray.Reference+        ( Similar(..), PprPhysical1 (..)+        , withRef1, withRef2+        , toRef1,   toRef2,   toRef3)+where+import Data.Array.Parallel.Pretty+import qualified Data.Array.Parallel.Array      as A+import qualified Data.Vector                    as V+import Data.Vector                              (Vector)+import Prelude hiding (length)+import System.IO+import System.IO.Unsafe+import Control.Monad++-- Config ---------------------------------------------------------------------+debugLiftedTrace        :: Bool+debugLiftedTrace        = False++debugLiftedCompare      :: Bool+debugLiftedCompare      = False++class Similar a where+ similar :: a -> a -> Bool++class PprPhysical1 a where+ pprp1  :: a -> Doc++ pprp1v :: Vector a -> Doc+ pprp1v vec+        = brackets +        $ hcat+        $ punctuate (text ", ") +        $ V.toList $ V.map pprp1 vec+        ++-- withRef --------------------------------------------------------------------+-- | Compare the result of some array operator against a reference.++--  Careful:+--   * We don't want to inline the whole body of this function into+--     every use site, or we'll get code explosion. When debugging is off we+--     want this wrapper to be inlined and eliminated as cheaply as possible.+--   * We also do this with 'unsafePerformIO' instead of trace, because+--     with trace, if the computation contructing the string throws an exception+--     then we get no output. For debugging we want to see what function was+--     entered before we try to print the result (which might be badly formed),+--+withRef1 :: ( A.Array r a+            , A.Array c a, PprPhysical1 (c a)+            , Similar a,   PprPhysical1 a)+         => String              -- name of operator+         -> r a                 -- result using reference implementation+         -> c a                 -- result using vseg implementation+         -> c a++{-# INLINE withRef1 #-}+withRef1 name arrRef arrImpl+ = if debugLiftedCompare || debugLiftedTrace+        then withRef1' name arrRef arrImpl+        else arrImpl+        +{-# NOINLINE withRef1' #-}+withRef1' name arrRef arrImpl+ = unsafePerformIO+ $ do   when debugLiftedTrace+         $ do putStrLn  $ "* " ++ name+              putStrLn  $ render (nest 4 $ pprp1 arrImpl)+              hFlush stdout+        +        when ( debugLiftedCompare +             && or [ not $ A.valid arrImpl+                   , not $ A.length arrRef == A.length arrImpl+                   , not $ V.and $ V.zipWith similar+                                (A.toVectors1 arrRef)+                                (A.toVectors1 arrImpl)])+         $ error $ render $ vcat+                [ text "withRef1: failure " <> text name+                , nest 4 $ pprp1v $ A.toVectors1 arrRef+                , nest 4 $ pprp1  $ arrImpl ]++        return arrImpl+++-- | Compare the nested result of some array operator against a reference.+withRef2 :: ( A.Array r (r a)+            , A.Array r a+            , A.Array c (c a), PprPhysical1 (c (c a))+            , A.Array c a,     PprPhysical1 (c a)+            , Similar a,       PprPhysical1 a)+         => String      -- name of operator.+         -> r (r a)     -- result using reference implementaiton.+         -> c (c a)     -- result using vseg implementation.+         -> c (c a)++{-# INLINE withRef2 #-}+withRef2 name arrRef arrImpl+ = if debugLiftedCompare || debugLiftedTrace+         then withRef2' name arrRef arrImpl+         else arrImpl++{-# NOINLINE withRef2' #-}+withRef2' name arrRef arrImpl+ = unsafePerformIO+ $ do   when debugLiftedTrace+         $ do putStrLn  $ "* " ++ name+              putStrLn  $ render (nest 4 $ pprp1 arrImpl)+              hFlush stdout++        when ( debugLiftedCompare+             && or [ not $ A.valid arrImpl+                   , not $ A.length arrRef == A.length arrImpl+                   , not $ V.and $ V.zipWith +                                (\xs ys -> V.and $ V.zipWith similar xs ys)+                                (A.toVectors2 arrRef)+                                (A.toVectors2 arrImpl) ])+         $ error $ render $ vcat+                [ text "withRef2: failure " <> text name+                , nest 4 $ pprp1 arrImpl ]++        return arrImpl+++-- toRef ----------------------------------------------------------------------+-- | Convert an array to the reference version.+toRef1  :: ( A.Array c a+           , A.Array r a)+        => c a -> r a++toRef1  = A.fromVectors1 . A.toVectors1+{-# NOINLINE toRef1 #-}+--  NOINLINE because it's only for debugging.+++-- | Convert a nested array to the reference version.+toRef2 :: ( A.Array c (c a)+          , A.Array c a+          , A.Array r (r a)+          , A.Array r a)+       => c (c a)+       -> r (r a)++toRef2  = A.fromVectors2 . A.toVectors2+{-# NOINLINE toRef2 #-}+--  NOINLINE because it's only for debugging.+++-- | Convert a doubly nested array to the reference version.+toRef3 :: ( A.Array c (c (c a))+          , A.Array c (c a)+          , A.Array c a+          , A.Array r (r (r a))+          , A.Array r (r a)+          , A.Array r a)+       => c (c (c a))+       -> r (r (r a))++toRef3  = A.fromVectors3 . A.toVectors3+{-# NOINLINE toRef3 #-}+--  NOINLINE because it's only for debugging.
+ Data/Array/Parallel/PArray/Types.hs view
@@ -0,0 +1,116 @@+{-# LANGUAGE CPP #-}+#include "fusion-phases.h"++-- | Defines the extra types we use when representing algebraic data in+--   parallel arrays. We don't store values of user defined algebraic type+--   directly in PArrays. Instead, we convert these to a generic representation+--   and store that representation.+--+--   Conversion to and from the generic representation is handled by the+--   methods of the PA class defined in "Data.Array.Parallel.PArray.PRepr".+--+---  For further information see:+--     "Instant Generics: Fast and Easy", Chakravarty, Ditu and Keller, 2009+-- +module Data.Array.Parallel.PArray.Types +        ( -- * The Void type+          Void+        , void+        , fromVoid++          -- * Generic sums+        , Sum2(..), tagOfSum2+        , Sum3(..), tagOfSum3+        +          -- * The Wrap type+        , Wrap (..))+where+import Data.Array.Parallel.Base (Tag)+import Data.Array.Parallel.Pretty+++-- Void -----------------------------------------------------------------------+-- | The `Void` type is used when representing enumerations. +-- +--   A type like Bool is represented as @Sum2 Void Void@, meaning that we only+--   only care about the tag of the data constructor and not its argumnent.+-- +data Void++-- | A 'value' with the void type. Used as a placholder like `undefined`.+--   Forcing this yields `error`. +void    :: Void+void     = error $ unlines+         [ "Data.Array.Parallel.PArray.Types.void"+         , "  With the DPH generic array representation, values of type void"+         , "  should never be forced. Something has gone badly wrong." ]+++-- | Coerce a `Void` to a different type. Used as a placeholder like `undefined`.+--   Forcing the result yields `error`.+fromVoid :: a+fromVoid = error $ unlines+         [ "Data.Array.Parallel.PArray.Types.fromVoid"+         , "  With the DPH generic array representation, values of type void"+         , "  should never be forced. Something has gone badly wrong." ]+++-- Sum2 -----------------------------------------------------------------------+-- | Sum types used for the generic representation of algebraic data.+data Sum2 a b+        = Alt2_1 a | Alt2_2 b++tagOfSum2 :: Sum2 a b -> Tag+tagOfSum2 ss+ = case ss of+        Alt2_1 _        -> 0+        Alt2_2 _        -> 1+{-# INLINE tagOfSum2 #-}+++instance (PprPhysical a, PprPhysical b)+        => PprPhysical (Sum2 a b) where+ pprp ss+  = case ss of+        Alt2_1 x        -> text "Alt2_1" <+> pprp x+        Alt2_2 y        -> text "Alt2_2" <+> pprp y+++-- Sum3 -----------------------------------------------------------------------+data Sum3 a b c+        = Alt3_1 a | Alt3_2 b | Alt3_3 c++tagOfSum3 :: Sum3 a b c -> Tag+tagOfSum3 ss+ = case ss of+        Alt3_1 _        -> 0+        Alt3_2 _        -> 1+        Alt3_3 _        -> 2+{-# INLINE tagOfSum3 #-}+++-- Wrap -----------------------------------------------------------------------+-- | When converting a data type to its generic representation, we use+--   `Wrap` to help us convert only one layer at a time. For example:+--+--   @+--   data Foo a = Foo Int a+--+--   instance PA a => PA (Foo a) where+--    type PRepr (Foo a) = (Int, Wrap a)  -- define how (Foo a) is represented+--   @+--+--   Here we've converted the @Foo@ data constructor to a pair, and Int+--   is its own representation type. We have PData/PR instances for pairs and+--   Ints, so we can work with arrays of these types. However, we can't just+--   use (Int, a) as the representation of (Foo a) because 'a' might+--   be user defined and we won't have PData/PR instances for it.+--+--   Instead, we wrap the second element with the Wrap constructor, which tells+--   us that if we want to process this element we still need to convert it+--   to the generic representation (and back). This last part is done by+--   the PR instance of Wrap, who's methods are defined by calls to the *PD +--   functions from "Data.Array.Parallel.PArray.PRepr".+--+newtype Wrap a = Wrap { unWrap :: a }+
+ LICENSE view
@@ -0,0 +1,36 @@+Copyright (c) 2001-2012, The DPH Team++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-lifted-base.cabal view
@@ -0,0 +1,65 @@+Name:           dph-lifted-base+Version:        0.6.0.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:       Data Parallel Haskell common definitions used by other dph-lifted packages.++Cabal-Version:  >= 1.6+Build-Type:     Simple++Library+  Exposed-Modules:+        Data.Array.Parallel.PArray.Types+        Data.Array.Parallel.PArray.Reference+        Data.Array.Parallel.PArray+        Data.Array.Parallel.PArr+        +  Exposed:+        False++  Extensions:+        BangPatterns,+        PatternGuards+        TypeFamilies,+        TypeOperators,+        RankNTypes,+        BangPatterns,+        MagicHash,+        UnboxedTuples,+        TypeOperators,+        FlexibleContexts,+        FlexibleInstances,+        EmptyDataDecls,+        NoMonomorphismRestriction,+        MultiParamTypeClasses,+        EmptyDataDecls,+        StandaloneDeriving,+        ExplicitForAll,+        ParallelListComp,+        ExistentialQuantification,+        ScopedTypeVariables,+        PatternGuards,+        PackageImports++  GHC-Options:+        -Odph +        -fcpr-off -fno-liberate-case -fno-spec-constr+        -Wall+        -fno-warn-missing-methods+        -fno-warn-orphans++  Build-Depends:  +        base                    == 4.5.*,+        ghc                     == 7.*,+        array                   == 0.4.*,+        random                  == 1.0.*,+        template-haskell        == 2.7.*,+        dph-base                == 0.6.*,+        dph-prim-par            == 0.6.*,+        vector                  == 0.9.*,+        pretty                  == 1.1.*,+        containers              == 0.4.*