Separate length from data in array representation
authorRoman Leshchinskiy <rl@cse.unsw.edu.au>
Mon, 13 Jul 2009 04:44:35 +0000 (04:44 +0000)
committerRoman Leshchinskiy <rl@cse.unsw.edu.au>
Mon, 13 Jul 2009 04:44:35 +0000 (04:44 +0000)
13 files changed:
dph-common/Data/Array/Parallel/Lifted/Closure.hs
dph-common/Data/Array/Parallel/Lifted/Combinators.hs
dph-common/Data/Array/Parallel/Lifted/Instances.hs
dph-common/Data/Array/Parallel/Lifted/PArray.hs
dph-common/Data/Array/Parallel/Lifted/Repr.hs
dph-common/Data/Array/Parallel/Lifted/Scalar.hs
dph-common/Data/Array/Parallel/Lifted/Unboxed.hs
dph-common/Data/Array/Parallel/Prelude.hs
dph-common/Data/Array/Parallel/Prelude/Base/Int.hs
dph-common/Data/Array/Parallel/Prelude/Base/Tuple.hs
dph-common/dph-common.cabal
dph-prim-interface/interface/DPH_Header.h
dph-prim-interface/interface/DPH_Interface.h

index 1854e57..7c314b4 100644 (file)
@@ -1,6 +1,7 @@
 module Data.Array.Parallel.Lifted.Closure (
   (:->)(..), PArray(..),
   mkClosure, mkClosureP, ($:), ($:^),
+  closure, liftedClosure, liftedApply,
   dPA_Clo, dPR_Clo,
 
   closure1, closure2, closure3
@@ -10,6 +11,8 @@ import Data.Array.Parallel.Lifted.PArray
 import Data.Array.Parallel.Lifted.Instances  (dPA_Unit, dPA_2, dPA_3)
 import Data.Array.Parallel.Lifted.Repr
 
+import GHC.Exts (Int#)
+
 infixr 0 :->
 infixl 0 $:, $:^
 
@@ -17,9 +20,14 @@ infixl 0 $:, $:^
 --
 data a :-> b = forall e. Clo (PA e)
                              !(e -> a -> b)
-                             !(PArray e -> PArray a -> PArray b)
+                             !(Int# -> PData e -> PData a -> PData b)
                              e
 
+lifted :: (PArray e -> PArray a -> PArray b)
+       -> Int# -> PData e -> PData a -> PData b
+{-# INLINE lifted #-}
+lifted f n# es as = case f (PArray n# es) (PArray n# as) of PArray _ bs -> bs
+
 -- |Closure construction
 --
 mkClosure :: forall a b e. 
@@ -27,7 +35,15 @@ mkClosure :: forall a b e.
                   -> (PArray e -> PArray a -> PArray b)
                   -> e -> (a :-> b)
 {-# INLINE CONLIKE mkClosure #-}
-mkClosure = Clo
+mkClosure pa fv fl e = Clo pa fv (lifted fl) e
+
+closure :: forall a b e.
+           PA e -> (e -> a -> b)
+                -> (Int# -> PData e -> PData a -> PData b)
+                -> e
+                -> (a :-> b)
+{-# INLINE closure #-}
+closure pa fv fl e = Clo pa fv fl e
 
 -- |Closure application
 --
@@ -44,11 +60,11 @@ Clo _ f _ e $: a = f e a
 
 -- |Arrays of closures (aka array closures)
 --
-data instance PArray (a :-> b)
+data instance PData (a :-> b)
   = forall e. AClo (PA e)
                    !(e -> a -> b)
-                   !(PArray e -> PArray a -> PArray b)
-                   !(PArray e)
+                   !(Int# -> PData e -> PData a -> PData b)
+                    (PData e)
 
 -- |Lifted closure construction
 --
@@ -57,13 +73,25 @@ mkClosureP :: forall a b e.
                    -> (PArray e -> PArray a -> PArray b)
                    -> PArray e -> PArray (a :-> b)
 {-# INLINE mkClosureP #-}
-mkClosureP = AClo
+mkClosureP pa fv fl (PArray n# es) = PArray n# (AClo pa fv (lifted fl) es)
+
+liftedClosure :: forall a b e.
+                 PA e -> (e -> a -> b)
+                      -> (Int# -> PData e -> PData a -> PData b)
+                      -> PData e
+                      -> PData (a :-> b)
+{-# INLINE liftedClosure #-}
+liftedClosure pa fv fl es = AClo pa fv fl es
 
 -- |Lifted closure application
 --
 ($:^) :: forall a b. PArray (a :-> b) -> PArray a -> PArray b
 {-# INLINE ($:^) #-}
-AClo _ _ f es $:^ as = f es as
+PArray n# (AClo _ _ f es) $:^ PArray _ as = PArray n# (f n# es as)
+
+liftedApply :: forall a b. Int# -> PData (a :-> b) -> PData a -> PData b
+{-# INLINE liftedApply #-}
+liftedApply n# (AClo _ _ f es) as = f n# es as
 
 type instance PRepr (a :-> b) = a :-> b
 
@@ -80,8 +108,7 @@ dPA_Clo _ _ = PA {
 dPR_Clo :: PR (a :-> b)
 {-# INLINE dPR_Clo #-}
 dPR_Clo = PR {
-            lengthPR     = lengthPR_Clo
-          , emptyPR      = emptyPR_Clo
+            emptyPR      = emptyPR_Clo
           , replicatePR  = replicatePR_Clo
           , replicatelPR = replicatelPR_Clo
           , indexPR      = indexPR_Clo
@@ -89,59 +116,56 @@ dPR_Clo = PR {
           , packPR       = packPR_Clo
           }
 
-{-# INLINE lengthPR_Clo #-}
-lengthPR_Clo (AClo pa f f' es) = lengthPA# pa es
-
 {-# INLINE emptyPR_Clo #-}
 emptyPR_Clo = AClo dPA_Unit (\e  a  -> error "empty array closure")
                             (\es as -> error "empty array closure")
-                            (emptyPA dPA_Unit)
+                            (emptyPD dPA_Unit)
 
 {-# INLINE replicatePR_Clo #-}
-replicatePR_Clo n# (Clo pa f f' e) = AClo pa f f' (replicatePA# pa n# e)
+replicatePR_Clo n# (Clo pa f f' e) = AClo pa f f' (replicatePD pa n# e)
 
 {-# INLINE replicatelPR_Clo #-}
 replicatelPR_Clo segd (AClo pa f f' es)
-  = AClo pa f f' (replicatelPA# pa segd es)
+  = AClo pa f f' (replicatelPD pa segd es)
 
 {-# INLINE indexPR_Clo #-}
-indexPR_Clo (AClo pa f f' es) i# = Clo pa f f' (indexPA# pa es i#)
+indexPR_Clo (AClo pa f f' es) i# = Clo pa f f' (indexPD pa es i#)
 
 {-# INLINE bpermutePR_Clo #-}
-bpermutePR_Clo n# (AClo pa f f' es) is = AClo pa f f' (bpermutePA# pa n# es is)
+bpermutePR_Clo (AClo pa f f' es) n# is = AClo pa f f' (bpermutePD pa es n# is)
 
 {-# INLINE packPR_Clo #-}
-packPR_Clo (AClo pa f f' es) n# sel# = AClo pa f f' (packPA# pa es n# sel#)
+packPR_Clo (AClo pa f f' es) n# sel = AClo pa f f' (packPD pa es n# sel)
 
 -- Closure construction
 
 closure1 :: (a -> b) -> (PArray a -> PArray b) -> (a :-> b)
 {-# INLINE closure1 #-}
-closure1 fv fl = Clo dPA_Unit (\_ -> fv) (\_ -> fl) ()
+closure1 fv fl = mkClosure dPA_Unit (\_ -> fv) (\_ -> fl) ()
 
 closure2 :: PA a
          -> (a -> b -> c)
          -> (PArray a -> PArray b -> PArray c)
          -> (a :-> b :-> c)
 {-# INLINE closure2 #-}
-closure2 pa fv fl = Clo dPA_Unit fv_1 fl_1 ()
+closure2 pa fv fl = mkClosure dPA_Unit fv_1 fl_1 ()
   where
-    fv_1 _ x  = Clo  pa fv fl x
-    fl_1 _ xs = AClo pa fv fl xs
+    fv_1 _ x  = mkClosure  pa fv fl x
+    fl_1 _ xs = mkClosureP pa fv fl xs
 
 closure3 :: PA a -> PA b
          -> (a -> b -> c -> d)
          -> (PArray a -> PArray b -> PArray c -> PArray d)
          -> (a :-> b :-> c :-> d)
 {-# INLINE closure3 #-}
-closure3 pa pb fv fl = Clo dPA_Unit fv_1 fl_1 ()
+closure3 pa pb fv fl = mkClosure dPA_Unit fv_1 fl_1 ()
   where
-    fv_1 _  x  = Clo  pa fv_2 fl_2 x
-    fl_1 _  xs = AClo pa fv_2 fl_2 xs
+    fv_1 _  x  = mkClosure  pa fv_2 fl_2 x
+    fl_1 _  xs = mkClosureP pa fv_2 fl_2 xs
 
-    fv_2 x  y  = Clo  (dPA_2 pa pb) fv_3 fl_3 (x,y)
-    fl_2 xs ys = AClo (dPA_2 pa pb) fv_3 fl_3 (P_2 (lengthPA# pa xs) xs ys)
+    fv_2 x  y  = mkClosure  (dPA_2 pa pb) fv_3 fl_3 (x,y)
+    fl_2 xs ys = mkClosureP (dPA_2 pa pb) fv_3 fl_3 (zipPA# xs ys)
 
     fv_3 (x,y) z = fv x y z
-    fl_3 (P_2 _ xs ys) zs = fl xs ys zs
+    fl_3 ps zs = case unzipPA# ps of (xs,ys) -> fl xs ys zs
 
index 88d6371..a2b0fb5 100644 (file)
@@ -13,19 +13,26 @@ module Data.Array.Parallel.Lifted.Combinators (
 
 import Data.Array.Parallel.Lifted.PArray
 import Data.Array.Parallel.Lifted.Closure
-import Data.Array.Parallel.Lifted.Unboxed
+import Data.Array.Parallel.Lifted.Unboxed ( elementsSegd# )
 import Data.Array.Parallel.Lifted.Repr
 import Data.Array.Parallel.Lifted.Instances
+import Data.Array.Parallel.Lifted.Scalar
+import Data.Array.Parallel.Lifted.Selector
+
+import qualified Data.Array.Parallel.Unlifted as U
+import Data.Array.Parallel.Base ( fromBool )
 
 import GHC.Exts (Int(..), (+#), (-#), Int#, (<#))
 
 lengthPA_v :: PA a -> PArray a -> Int
 {-# INLINE_PA lengthPA_v #-}
-lengthPA_v pa xs = I# (lengthPA# pa xs)
+lengthPA_v pa xs = I# (lengthPA# xs)
 
 lengthPA_l :: PA a -> PArray (PArray a) -> PArray Int
 {-# INLINE_PA lengthPA_l #-}
-lengthPA_l pa (PNested n# lens _ _) = PInt n# lens
+lengthPA_l pa xss = fromUArrPA (U.elementsSegd segd) (U.lengthsSegd segd)
+  where
+    segd = segdPA# xss
 
 lengthPA :: PA a -> (PArray a :-> Int)
 {-# INLINE lengthPA #-}
@@ -37,11 +44,8 @@ replicatePA_v pa (I# n#) x = replicatePA# pa n# x
 
 replicatePA_l :: PA a -> PArray Int -> PArray a -> PArray (PArray a)
 {-# INLINE_PA replicatePA_l #-}
-replicatePA_l pa (PInt n# ns) xs
-  = PNested n# ns (indicesSegdPA# segd)
-                  (replicatelPA# pa segd xs)
-  where
-    segd = lengthsToSegdPA# ns
+replicatePA_l pa (PArray n# (PInt ns)) (PArray _ xs)
+  = PArray n# (PNested (U.lengthsToSegd ns) xs)
 
 replicatePA :: PA a -> (Int :-> a :-> PArray a)
 {-# INLINE replicatePA #-}
@@ -53,9 +57,11 @@ singletonPA_v pa x = replicatePA_v pa 1 x
 
 singletonPA_l :: PA a -> PArray a -> PArray (PArray a)
 {-# INLINE_PA singletonPA_l #-}
-singletonPA_l pa xs
-  = case lengthPA# pa xs of
-      n# -> PNested n# (replicatePA_Int# n# 1#) (upToPA_Int# n#) xs
+singletonPA_l pa (PArray n# xs)
+  = PArray n# (PNested (U.mkSegd (U.replicate (I# n#) 1)
+                                 (U.enumFromStepLen 0 1 (I# n#))
+                                 (I# n#))
+                       xs)
 
 singletonPA :: PA a -> (a :-> PArray a)
 {-# INLINE singletonPA #-}
@@ -63,15 +69,15 @@ singletonPA pa = closure1 (singletonPA_v pa) (singletonPA_l pa)
 
 mapPA_v :: PA a -> PA b -> (a :-> b) -> PArray a -> PArray b
 {-# INLINE_PA mapPA_v #-}
-mapPA_v pa pb f as = replicatePA# (dPA_Clo pa pb) (lengthPA# pa as) f
+mapPA_v pa pb f as = replicatePA# (dPA_Clo pa pb) (lengthPA# as) f
                      $:^ as
 
 mapPA_l :: PA a -> PA b
         -> PArray (a :-> b) -> PArray (PArray a) -> PArray (PArray b)
 {-# INLINE_PA mapPA_l #-}
-mapPA_l pa pb fs xss@(PNested n# lens idxs xs)
-  = PNested n# lens idxs
-            (replicatelPA# (dPA_Clo pa pb) (segdOfPA# pa xss) fs $:^ xs)
+mapPA_l pa pb fs xss
+  = copySegdPA# xss
+      (replicatelPA# (dPA_Clo pa pb) (segdPA# xss) fs $:^ concatPA# xss)
 
 mapPA :: PA a -> PA b -> ((a :-> b) :-> PArray a :-> PArray b)
 {-# INLINE mapPA #-}
@@ -80,7 +86,7 @@ mapPA pa pb = closure2 (dPA_Clo pa pb) (mapPA_v pa pb) (mapPA_l pa pb)
 crossMapPA_v :: PA a -> PA b -> PArray a -> (a :-> PArray b) -> PArray (a,b)
 {-# INLINE_PA crossMapPA_v #-}
 crossMapPA_v pa pb as f
-  = zipPA# pa pb (replicatelPA# pa (segdOfPA# pb bss) as) (concatPA# bss)
+  = zipPA# (replicatelPA# pa (segdPA# bss) as) (concatPA# bss)
   where
     bss = mapPA_v pa (dPA_PArray pb) f as
 
@@ -89,14 +95,11 @@ crossMapPA_l :: PA a -> PA b
              -> PArray (a :-> PArray b)
              -> PArray (PArray (a,b))
 {-# INLINE_PA crossMapPA_l #-}
-crossMapPA_l pa pb ass@(PNested _ _ _ as) fs
-  = case concatPA_l pb bsss of
-      PNested n# lens1 idxs1 bs -> PNested n# lens1 idxs1 (zipPA# pa pb as' bs)
+crossMapPA_l pa pb ass fs = copySegdPA# bss (zipPA# as' (concatPA# bss))
   where
-    bsss@(PNested _ _ _ bss)
-      = mapPA_l pa (dPA_PArray pb) fs ass
-
-    as' = replicatelPA# pa (segdOfPA# pb bss) as
+    bsss = mapPA_l pa (dPA_PArray pb) fs ass
+    bss  = concatPA_l pb bsss
+    as' = replicatelPA# pa (segdPA# (concatPA# bsss)) (concatPA# ass)
 
 crossMapPA :: PA a -> PA b -> (PArray a :-> (a :-> PArray b) :-> PArray (a,b))
 {-# INLINE crossMapPA #-}
@@ -105,13 +108,12 @@ crossMapPA pa pb = closure2 (dPA_PArray pa) (crossMapPA_v pa pb)
 
 zipPA_v :: PA a -> PA b -> PArray a -> PArray b -> PArray (a,b)
 {-# INLINE_PA zipPA_v #-}
-zipPA_v pa pb xs ys = zipPA# pa pb xs ys
+zipPA_v pa pb xs ys = zipPA# xs ys
 
 zipPA_l :: PA a -> PA b
         -> PArray (PArray a) -> PArray (PArray b) -> PArray (PArray (a,b))
 {-# INLINE_PA zipPA_l #-}
-zipPA_l pa pb (PNested n# lens idxs xs) (PNested _ _ _ ys)
-  = PNested n# lens idxs (zipPA_v pa pb xs ys)
+zipPA_l pa pb xss yss = copySegdPA# xss (zipPA# (concatPA# xss) (concatPA# yss))
 
 zipPA :: PA a -> PA b -> (PArray a :-> PArray b :-> PArray (a,b))
 {-# INLINE zipPA #-}
@@ -121,7 +123,7 @@ zipWithPA_v :: PA a -> PA b -> PA c
             -> (a :-> b :-> c) -> PArray a -> PArray b -> PArray c
 {-# INLINE_PA zipWithPA_v #-}
 zipWithPA_v pa pb pc f as bs = replicatePA# (dPA_Clo pa (dPA_Clo pb pc))
-                                            (lengthPA# pa as)
+                                            (lengthPA# as)
                                             f
                                 $:^ as $:^ bs
 
@@ -129,10 +131,10 @@ zipWithPA_l :: PA a -> PA b -> PA c
             -> PArray (a :-> b :-> c) -> PArray (PArray a) -> PArray (PArray b)
             -> PArray (PArray c)
 {-# INLINE_PA zipWithPA_l #-}
-zipWithPA_l pa pb pc fs ass@(PNested n# lens idxs as) (PNested _ _ _ bs)
-  = PNested n# lens idxs
-            (replicatelPA# (dPA_Clo pa (dPA_Clo pb pc))
-                           (segdOfPA# pa ass) fs $:^ as $:^ bs)
+zipWithPA_l pa pb pc fs ass bss
+  = copySegdPA# ass
+      (replicatelPA# (dPA_Clo pa (dPA_Clo pb pc))
+                     (segdPA# ass) fs $:^ concatPA# ass $:^ concatPA# bss)
 
 zipWithPA :: PA a -> PA b -> PA c
           -> ((a :-> b :-> c) :-> PArray a :-> PArray b :-> PArray c)
@@ -142,13 +144,14 @@ zipWithPA pa pb pc = closure3 (dPA_Clo pa (dPA_Clo pb pc)) (dPA_PArray pa)
                               (zipWithPA_l pa pb pc)
 
 unzipPA_v:: PA a -> PA b -> PArray (a,b) -> (PArray a, PArray b)
-unzipPA_v pa pb abs =  unzipPA# pa pb abs
+{-# INLINE_PA unzipPA_v #-}
+unzipPA_v pa pb abs = unzipPA# abs
 
-unzipPA_l:: PA a -> PA b -> PArray (PArray (a, b)) -> PArray ((PArray a), (PArray b))
-unzipPA_l pa pb (PNested n lens idxys xys) = 
-  P_2 n  (PNested n lens idxys xs) (PNested n lens idxys ys)
+unzipPA_l:: PA a -> PA b -> PArray (PArray (a, b)) -> PArray (PArray a, PArray b)
+{-# INLINE_PA unzipPA_l #-}
+unzipPA_l pa pb xyss = zipPA# (copySegdPA# xyss xs) (copySegdPA# xyss ys)
   where
-    (xs, ys) = unzipPA_v pa pb xys     
+    (xs, ys) = unzipPA# (concatPA# xyss)
 
 unzipPA:: PA a -> PA b -> (PArray (a, b) :-> (PArray a, PArray b))  
 {-# INLINE unzipPA #-}
@@ -156,18 +159,20 @@ unzipPA pa pb =  closure1 (unzipPA_v pa pb) (unzipPA_l pa pb)
 
 packPA_v :: PA a -> PArray a -> PArray Bool -> PArray a
 {-# INLINE_PA packPA_v #-}
-packPA_v pa xs bs = packPA# pa xs (truesPA# bs) (toPrimArrPA_Bool bs)
+packPA_v pa xs bs
+  = case U.count (toUArrPA bs) True of I# n# -> packPA# pa xs n# (toUArrPA bs)
 
 packPA_l :: PA a
          -> PArray (PArray a) -> PArray (PArray Bool) -> PArray (PArray a)
 {-# INLINE_PA packPA_l #-}
-packPA_l pa (PNested _ _ _ xs) bss
-  = PNested (lengthPA# (dPA_PArray dPA_Bool) bss) lens' idxs' (packPA_v pa xs bs)
+packPA_l pa xss bss
+  = segmentPA# (lengthPA# xss) (segdPA# xss)
+  $ packPA# pa (concatPA# xss) (elementsSegd# segd') (toUArrPA (concatPA# bss))
   where
-    lens' = truesPAs_Bool# segd (toPrimArrPA_Bool bs)
-    idxs' = unsafe_scanPA_Int# (+) 0 lens'
-    segd  = segdOfPA# dPA_Bool bss
-    bs    = concatPA# bss
+    segd' = U.lengthsToSegd
+          . U.sum_s (segdPA# xss)
+          . U.map fromBool
+          $ toUArrPA (concatPA# bss)
 
 packPA :: PA a -> (PArray a :-> PArray Bool :-> PArray a)
 {-# INLINE packPA #-}
@@ -175,11 +180,12 @@ packPA pa = closure2 (dPA_PArray pa) (packPA_v pa) (packPA_l pa)
 
 
 -- TODO: should the selector be a boolean array?
---       fix index vector
 combine2PA_v:: PA a -> PArray a -> PArray a -> PArray Int -> PArray a
 {-# INLINE_PA combine2PA_v #-}
-combine2PA_v pa xs ys bs@(PInt _ bs#) = 
-  combine2PA# pa (lengthPA# pa xs +# lengthPA# pa ys) bs# bs# xs ys
+combine2PA_v pa xs ys bs
+  = combine2PA# pa (lengthPA# xs +# lengthPA# ys)
+                   (tagsToSel2 (toUArrPA bs))
+                   xs ys
 
 combine2PA_l:: PA a -> PArray (PArray a) -> PArray (PArray a) -> PArray (PArray Int) -> PArray (PArray a)
 {-# INLINE_PA combine2PA_l #-}
@@ -210,8 +216,10 @@ indexPA_v pa xs (I# i#) = indexPA# pa xs i#
 
 indexPA_l :: PA a -> PArray (PArray a) -> PArray Int -> PArray a
 {-# INLINE_PA indexPA_l #-}
-indexPA_l pa (PNested _ lens idxs xs) (PInt n# is)
-  = bpermutePA# pa n# xs (unsafe_zipWithPA_Int# (+) idxs is)
+indexPA_l pa xss is
+  = bpermutePA# pa (concatPA# xss)
+                   (lengthPA# xss)
+                   (U.zipWith (+) (U.indicesSegd (segdPA# xss)) (toUArrPA is))
 
 indexPA :: PA a -> (PArray a :-> Int :-> a)
 {-# INLINE indexPA #-}
@@ -219,16 +227,16 @@ indexPA pa = closure2 (dPA_PArray pa) (indexPA_v pa) (indexPA_l pa)
 
 concatPA_v :: PA a -> PArray (PArray a) -> PArray a
 {-# INLINE_PA concatPA_v #-}
-concatPA_v pa (PNested _ _ _ xs) = xs
+concatPA_v pa xss = concatPA# xss
 
 concatPA_l :: PA a -> PArray (PArray (PArray a)) -> PArray (PArray a)
 {-# INLINE_PA concatPA_l #-}
-concatPA_l pa arr@(PNested m# lens1 idxs1 (PNested n# lens2 idxs2 xs))
-  = PNested m# lens idxs xs
-  where
-    lens = sumPAs_Int# segd lens2
-    idxs = bpermutePA_Int# idxs2 idxs1
-    segd = segdOfPA# (dPA_PArray pa) arr
+concatPA_l pa (PArray m# (PNested segd1 (PNested segd2 xs)))
+  = PArray m#
+      (PNested (U.mkSegd (U.sum_s segd1 (U.lengthsSegd segd2))
+                         (U.bpermute (U.indicesSegd segd2) (U.indicesSegd segd1))
+                         (U.elementsSegd segd2))
+               xs)
 
 concatPA :: PA a -> (PArray (PArray a) :-> PArray a)
 {-# INLINE concatPA #-}
@@ -240,12 +248,19 @@ appPA_v pa xs ys = appPA# pa xs ys
 
 appPA_l :: PA a -> PArray (PArray a) -> PArray (PArray a) -> PArray (PArray a)
 {-# INLINE_PA appPA_l #-}
-appPA_l pa xss@(PNested m# lens1 idxs1 xs)
-           yss@(PNested n# lens2 idxs2 ys)
-  = PNested (m# +# n#) (unsafe_zipWithPA_Int# (+) lens1 lens2)
-                       (unsafe_zipWithPA_Int# (+) idxs1 idxs2)
-                       (applPA# pa (segdOfPA# pa xss) xs
-                                   (segdOfPA# pa yss) ys)
+appPA_l pa xss yss
+  = segmentPA# (lengthPA# xss +# lengthPA# yss)
+               segd
+               xys
+  where
+    xsegd = segdPA# xss
+    ysegd = segdPA# yss
+
+    segd = U.mkSegd (U.zipWith (+) (U.lengthsSegd xsegd) (U.lengthsSegd ysegd))
+                    (U.zipWith (+) (U.indicesSegd xsegd) (U.indicesSegd ysegd))
+                    (U.elementsSegd xsegd + U.elementsSegd ysegd)
+
+    xys  = applPA# pa xsegd (concatPA# xss) ysegd (concatPA# yss) 
 
 appPA :: PA a -> (PArray a :-> PArray a :-> PArray a)
 {-# INLINE appPA #-}
@@ -254,25 +269,22 @@ appPA pa = closure2 (dPA_PArray pa) (appPA_v pa) (appPA_l pa)
 
 enumFromToPA_v :: Int -> Int -> PArray Int
 {-# INLINE_PA enumFromToPA_v #-}
-enumFromToPA_v m@(I# m#) n@(I# n#) = PInt len# (enumFromToPA_Int# m# n#)
-  where
-    !len# = max# 0# (n# -# m# +# 1#) -- case max 0 (n-m+1) of I# i# -> i#
+enumFromToPA_v m n = fromUArrPA (distance m n) (U.enumFromTo m n)
 
-max# :: Int# -> Int# -> Int#
-{-# INLINE_STREAM max# #-}
-max# m# n# = if m# <# n# then n# else m#
+distance :: Int -> Int -> Int
+{-# INLINE_STREAM distance #-}
+distance m n = max 0 (n - m + 1)
 
 enumFromToPA_l :: PArray Int -> PArray Int -> PArray (PArray Int)
 {-# INLINE_PA enumFromToPA_l #-}
-enumFromToPA_l (PInt k# ms#) (PInt _ ns#) = PNested k# lens# idxs# (PInt n# is#)
+enumFromToPA_l ms ns
+  = segmentPA# (lengthPA# ms) segd
+  . fromUArrPA (I# (lengthPA# ms))
+  . U.enumFromToEach (U.elementsSegd segd)
+  $ U.zip (toUArrPA ms) (toUArrPA ns)
   where
-    lenOf m n = max 0 (n - m + 1)
-
-    lens# = unsafe_zipWithPA_Int# lenOf ms# ns#
-    idxs# = unsafe_scanPA_Int# (+) 0 lens#
-
-    !n#   = sumPA_Int# lens#
-    is#   = enumFromToEachPA_Int# n# ms# ns#
+    segd = U.lengthsToSegd
+         $ U.zipWith distance (toUArrPA ms) (toUArrPA ns)
 
 enumFromToPA_Int :: Int :-> Int :-> PArray Int
 {-# INLINE enumFromToPA_Int #-}
index e676f26..19f7fe3 100644 (file)
@@ -3,27 +3,30 @@
 #include "fusion-phases.h"
 
 module Data.Array.Parallel.Lifted.Instances (
-  PArray(..),
+  PData(..),
 
-  dPA_Int, dPR_Int, upToPA_Int,
+  dPA_Int, dPR_Int, {- upToPA_Int, -}
 
   dPA_Word8, dPR_Word8,
   dPA_Double, dPR_Double,
 
-  dPA_Bool, toPrimArrPA_Bool, truesPA#,
+  dPA_Bool, {- toPrimArrPA_Bool, truesPA#, -}
   dPA_Unit, dPA_2, dPA_3, dPA_4, dPA_5,
   dPA_PArray
 ) where
 
 import Data.Array.Parallel.Lifted.PArray
 import Data.Array.Parallel.Lifted.Repr
-import Data.Array.Parallel.Lifted.Unboxed
+import Data.Array.Parallel.Lifted.Unboxed ( elementsSegd# )
+import Data.Array.Parallel.Lifted.Selector
+
+import qualified Data.Array.Parallel.Unlifted as U
 
 import GHC.Exts    ( Int#, Int(..), (+#), (*#),
                      Double#, Double(..) )
 import GHC.Word    ( Word8(..) )
 
-data instance PArray Int = PInt Int# PArray_Int#
+newtype instance PData Int = PInt (U.Array Int)
 
 type instance PRepr Int = Int
 
@@ -40,8 +43,7 @@ dPA_Int = PA {
 dPR_Int :: PR Int
 {-# INLINE dPR_Int #-}
 dPR_Int = PR {
-            lengthPR     = lengthPR_Int
-          , emptyPR      = emptyPR_Int
+            emptyPR      = emptyPR_Int
           , replicatePR  = replicatePR_Int
           , replicatelPR = replicatelPR_Int
           , repeatPR     = repeatPR_Int
@@ -57,60 +59,61 @@ dPR_Int = PR {
           , nfPR         = nfPR_Int
           }
 
-{-# INLINE lengthPR_Int #-}
-lengthPR_Int (PInt n# _) = n#
-
 {-# INLINE emptyPR_Int #-}
-emptyPR_Int = PInt 0# emptyPA_Int#
+emptyPR_Int = PInt U.empty
 
 {-# INLINE replicatePR_Int #-}
-replicatePR_Int n# i = PInt n# (case i of I# i# -> replicatePA_Int# n# i#)
+replicatePR_Int n# i = PInt (U.replicate (I# n#) i)
 
 {-# INLINE replicatelPR_Int #-}
-replicatelPR_Int segd (PInt _ is) = PInt (elementsSegdPA# segd)
-                                         (replicatelPA_Int# segd is)
+replicatelPR_Int segd (PInt xs) = PInt (U.replicate_s segd xs)
 
 {-# INLINE repeatPR_Int #-}
-repeatPR_Int n# len# (PInt _ is) = PInt (n# *# len#) (repeatPA_Int# n# len# is)
+repeatPR_Int n# len# (PInt xs) = PInt (U.repeat (I# n#) (I# len#) xs)
 
 {-# INLINE repeatcPR_Int #-}
-repeatcPR_Int n# ns segd (PInt _ is)
-  = PInt n# (repeatcPA_Int# n# ns segd is)
+repeatcPR_Int n# ns segd (PInt xs) = PInt (U.repeat_c (I# n#) ns segd xs)
 
 {-# INLINE indexPR_Int #-}
-indexPR_Int (PInt _ ns) i# = I# (indexPA_Int# ns i#)
+indexPR_Int (PInt xs) i# = xs U.!: I# i#
 
 {-# INLINE extractPR_Int #-}
-extractPR_Int (PInt _ ns) i# n# = PInt n# (extractPA_Int# ns i# n#)
+extractPR_Int (PInt xs) i# n# = PInt (U.extract xs (I# i#) (I# n#))
 
+bpermutePR_Int :: T_bpermutePR Int
 {-# INLINE bpermutePR_Int #-}
-bpermutePR_Int n# (PInt _ ns) is = PInt n# (bpermutePA_Int# ns is)
+bpermutePR_Int (PInt xs) _ is = PInt (U.bpermute xs is)
 
 {-# INLINE appPR_Int #-}
-appPR_Int (PInt m# ms) (PInt n# ns) = PInt (m# +# n#) (appPA_Int# ms ns)
+appPR_Int (PInt xs) (PInt ys) = PInt (xs U.+:+ ys)
 
 {-# INLINE applPR_Int #-}
-applPR_Int is (PInt m# ms) js (PInt n# ns)
-  = PInt (m# +# n#) (applPA_Int# is ms js ns)
+applPR_Int xsegd (PInt xs) ysegd (PInt ys)
+  = PInt (U.append_s xsegd xs ysegd ys)
 
+packPR_Int :: T_packPR Int
 {-# INLINE packPR_Int #-}
-packPR_Int (PInt _ ns) n# bs = PInt n# (packPA_Int# ns n# bs)
+packPR_Int (PInt ns) n# bs = PInt (U.pack ns bs)
 
+combine2PR_Int :: T_combine2PR Int
 {-# INLINE combine2PR_Int #-}
-combine2PR_Int n# sel is (PInt _ xs) (PInt _ ys)
-  = PInt n# (combine2PA_Int# n# sel is xs ys)
+combine2PR_Int n# sel (PInt xs) (PInt ys)
+  = PInt (U.combine (U.pick (tagsSel2 sel) 0) xs ys)
 
+fromListPR_Int :: T_fromListPR Int
 {-# INLINE fromListPR_Int #-}
-fromListPR_Int n# xs = PInt n# (fromListPA_Int# n# xs)
+fromListPR_Int n# xs = PInt (U.fromList xs)
 
 {-# INLINE nfPR_Int #-}
-nfPR_Int (PInt xs) = xs `seq` ()
+nfPR_Int (PInt xs) = xs `seq` ()
 
+{-
 upToPA_Int :: Int -> PArray Int
 {-# INLINE_PA upToPA_Int #-}
 upToPA_Int (I# n#) = PInt n# (upToPA_Int# n#)
+-}
 
-data instance PArray Word8 = PWord8 Int# PArray_Word8#
+newtype instance PData Word8 = PWord8 (U.Array Word8)
 
 type instance PRepr Word8 = Word8
 
@@ -127,8 +130,7 @@ dPA_Word8 = PA {
 dPR_Word8 :: PR Word8
 {-# INLINE dPR_Word8 #-}
 dPR_Word8 = PR {
-            lengthPR     = lengthPR_Word8
-          , emptyPR      = emptyPR_Word8
+            emptyPR      = emptyPR_Word8
           , replicatePR  = replicatePR_Word8
           , replicatelPR = replicatelPR_Word8
           , repeatPR     = repeatPR_Word8
@@ -144,60 +146,56 @@ dPR_Word8 = PR {
           , nfPR         = nfPR_Word8
           }
 
-{-# INLINE lengthPR_Word8 #-}
-lengthPR_Word8 (PWord8 n# _) = n#
-
 {-# INLINE emptyPR_Word8 #-}
-emptyPR_Word8 = PWord8 0# emptyPA_Word8#
+emptyPR_Word8 = PWord8 U.empty
 
 {-# INLINE replicatePR_Word8 #-}
-replicatePR_Word8 n# d
-  = PWord8 n# (case d of W8# d# -> replicatePA_Word8# n# d#)
+replicatePR_Word8 n# i = PWord8 (U.replicate (I# n#) i)
 
 {-# INLINE replicatelPR_Word8 #-}
-replicatelPR_Word8 segd (PWord8 _ ds)
-  = PWord8 (elementsSegdPA# segd) (replicatelPA_Word8# segd ds)
+replicatelPR_Word8 segd (PWord8 xs) = PWord8 (U.replicate_s segd xs)
 
 {-# INLINE repeatPR_Word8 #-}
-repeatPR_Word8 n# len# (PWord8 _ is)
-  = PWord8 (n# *# len#) (repeatPA_Word8# n# len# is)
+repeatPR_Word8 n# len# (PWord8 xs) = PWord8 (U.repeat (I# n#) (I# len#) xs)
 
 {-# INLINE repeatcPR_Word8 #-}
-repeatcPR_Word8 n# ns segd (PWord8 _ is)
-  = PWord8 n# (repeatcPA_Word8# n# ns segd is)
+repeatcPR_Word8 n# ns segd (PWord8 xs) = PWord8 (U.repeat_c (I# n#) ns segd xs)
 
 {-# INLINE indexPR_Word8 #-}
-indexPR_Word8 (PWord8 _ ds) i# = W8# (indexPA_Word8# ds i#)
+indexPR_Word8 (PWord8 xs) i# = xs U.!: I# i#
 
 {-# INLINE extractPR_Word8 #-}
-extractPR_Word8 (PWord8 _ ns) i# n# = PWord8 n# (extractPA_Word8# ns i# n#)
+extractPR_Word8 (PWord8 xs) i# n# = PWord8 (U.extract xs (I# i#) (I# n#))
 
+bpermutePR_Word8 :: T_bpermutePR Word8
 {-# INLINE bpermutePR_Word8 #-}
-bpermutePR_Word8 n# (PWord8 _ ds) is
-  = PWord8 n# (bpermutePA_Word8# ds is)
+bpermutePR_Word8 (PWord8 xs) _ is = PWord8 (U.bpermute xs is)
 
 {-# INLINE appPR_Word8 #-}
-appPR_Word8 (PWord8 m# ms) (PWord8 n# ns)
-  = PWord8 (m# +# n#) (appPA_Word8# ms ns)
+appPR_Word8 (PWord8 xs) (PWord8 ys) = PWord8 (xs U.+:+ ys)
 
 {-# INLINE applPR_Word8 #-}
-applPR_Word8 is (PWord8 m# ms) js (PWord8 n# ns)
-  = PWord8 (m# +# n#) (applPA_Word8# is ms js ns)
+applPR_Word8 xsegd (PWord8 xs) ysegd (PWord8 ys)
+  = PWord8 (U.append_s xsegd xs ysegd ys)
 
+packPR_Word8 :: T_packPR Word8
 {-# INLINE packPR_Word8 #-}
-packPR_Word8 (PWord8 _ ns) n# bs = PWord8 n# (packPA_Word8# ns n# bs)
+packPR_Word8 (PWord8 ns) n# bs = PWord8 (U.pack ns bs)
 
+combine2PR_Word8 :: T_combine2PR Word8
 {-# INLINE combine2PR_Word8 #-}
-combine2PR_Word8 n# sel is (PWord8 _ xs) (PWord8 _ ys)
-  = PWord8 n# (combine2PA_Word8# n# sel is xs ys)
+combine2PR_Word8 n# sel (PWord8 xs) (PWord8 ys)
+  = PWord8 (U.combine (U.pick (tagsSel2 sel) 0) xs ys)
 
+fromListPR_Word8 :: T_fromListPR Word8
 {-# INLINE fromListPR_Word8 #-}
-fromListPR_Word8 n# xs = PWord8 n# (fromListPA_Word8# n# xs)
+fromListPR_Word8 n# xs = PWord8 (U.fromList xs)
 
 {-# INLINE nfPR_Word8 #-}
-nfPR_Word8 (PWord8 _ xs) = xs `seq` ()
+nfPR_Word8 (PWord8 xs) = xs `seq` ()
+
 
-data instance PArray Double = PDouble Int# PArray_Double#
+newtype instance PData Double = PDouble (U.Array Double)
 
 type instance PRepr Double = Double
 
@@ -214,8 +212,7 @@ dPA_Double = PA {
 dPR_Double :: PR Double
 {-# INLINE dPR_Double #-}
 dPR_Double = PR {
-            lengthPR     = lengthPR_Double
-          , emptyPR      = emptyPR_Double
+            emptyPR      = emptyPR_Double
           , replicatePR  = replicatePR_Double
           , replicatelPR = replicatelPR_Double
           , repeatPR     = repeatPR_Double
@@ -231,63 +228,59 @@ dPR_Double = PR {
           , nfPR         = nfPR_Double
           }
 
-{-# INLINE lengthPR_Double #-}
-lengthPR_Double (PDouble n# _) = n#
-
 {-# INLINE emptyPR_Double #-}
-emptyPR_Double = PDouble 0# emptyPA_Double#
+emptyPR_Double = PDouble U.empty
 
 {-# INLINE replicatePR_Double #-}
-replicatePR_Double n# d
-  = PDouble n# (case d of D# d# -> replicatePA_Double# n# d#)
+replicatePR_Double n# i = PDouble (U.replicate (I# n#) i)
 
 {-# INLINE replicatelPR_Double #-}
-replicatelPR_Double segd (PDouble _ ds)
-  = PDouble (elementsSegdPA# segd) (replicatelPA_Double# segd ds)
+replicatelPR_Double segd (PDouble xs) = PDouble (U.replicate_s segd xs)
 
 {-# INLINE repeatPR_Double #-}
-repeatPR_Double n# len# (PDouble _ is)
-  = PDouble (n# *# len#) (repeatPA_Double# n# len# is)
+repeatPR_Double n# len# (PDouble xs) = PDouble (U.repeat (I# n#) (I# len#) xs)
 
 {-# INLINE repeatcPR_Double #-}
-repeatcPR_Double n# ns segd (PDouble _ is)
-  = PDouble n# (repeatcPA_Double# n# ns segd is)
+repeatcPR_Double n# ns segd (PDouble xs) = PDouble (U.repeat_c (I# n#) ns segd xs)
 
 {-# INLINE indexPR_Double #-}
-indexPR_Double (PDouble _ ds) i# = D# (indexPA_Double# ds i#)
+indexPR_Double (PDouble xs) i# = xs U.!: I# i#
 
 {-# INLINE extractPR_Double #-}
-extractPR_Double (PDouble _ ns) i# n#
-  = PDouble n# (extractPA_Double# ns i# n#)
+extractPR_Double (PDouble xs) i# n# = PDouble (U.extract xs (I# i#) (I# n#))
 
+bpermutePR_Double :: T_bpermutePR Double
 {-# INLINE bpermutePR_Double #-}
-bpermutePR_Double n# (PDouble _ ds) is
-  = PDouble n# (bpermutePA_Double# ds is)
+bpermutePR_Double (PDouble xs) _ is = PDouble (U.bpermute xs is)
 
 {-# INLINE appPR_Double #-}
-appPR_Double (PDouble m# ms) (PDouble n# ns)
-  = PDouble (m# +# n#) (appPA_Double# ms ns)
+appPR_Double (PDouble xs) (PDouble ys) = PDouble (xs U.+:+ ys)
 
 {-# INLINE applPR_Double #-}
-applPR_Double is (PDouble m# ms) js (PDouble n# ns)
-  = PDouble (m# +# n#) (applPA_Double# is ms js ns)
+applPR_Double xsegd (PDouble xs) ysegd (PDouble ys)
+  = PDouble (U.append_s xsegd xs ysegd ys)
 
+packPR_Double :: T_packPR Double
 {-# INLINE packPR_Double #-}
-packPR_Double (PDouble _ ns) n# bs = PDouble n# (packPA_Double# ns n# bs)
+packPR_Double (PDouble ns) n# bs = PDouble (U.pack ns bs)
 
+combine2PR_Double :: T_combine2PR Double
 {-# INLINE combine2PR_Double #-}
-combine2PR_Double n# sel is (PDouble _ xs) (PDouble _ ys)
-  = PDouble n# (combine2PA_Double# n# sel is xs ys)
+combine2PR_Double n# sel (PDouble xs) (PDouble ys)
+  = PDouble (U.combine (U.pick (tagsSel2 sel) 0) xs ys)
 
+fromListPR_Double :: T_fromListPR Double
 {-# INLINE fromListPR_Double #-}
-fromListPR_Double n# xs = PDouble n# (fromListPA_Double# n# xs)
+fromListPR_Double n# xs = PDouble (U.fromList xs)
 
 {-# INLINE nfPR_Double #-}
-nfPR_Double (PDouble _ xs) = xs `seq` ()
+nfPR_Double (PDouble xs) = xs `seq` ()
+
+
+data instance PData Bool
+  = PBool Sel2
 
 type instance PRepr Bool = Sum2 Void Void
-data instance PArray Bool = PBool Int# PArray_Int# PArray_Int#
-                                  (PArray Void) (PArray Void)
 
 dPA_Bool :: PA Bool
 {-# INLINE_PA dPA_Bool #-}
@@ -308,18 +301,20 @@ fromPRepr_Bool (Alt2_1 _) = False
 fromPRepr_Bool (Alt2_2 _) = True
 
 {-# INLINE toArrPRepr_Bool #-}
-toArrPRepr_Bool (PBool n# sel# is# fs ts) = PSum2 n# sel# is# fs ts
+toArrPRepr_Bool (PBool sel) = PSum2 sel pvoid pvoid
 
 {-# INLINE fromArrPRepr_Bool #-}
-fromArrPRepr_Bool (PSum2 n# sel# is# fs ts) = PBool n# sel# is# fs ts
+fromArrPRepr_Bool (PSum2 sel _ _) = PBool sel
 
-toPrimArrPA_Bool :: PArray Bool -> PArray_Bool#
+{-
+toPrimArrPA_Bool :: PArray Bool -> U.Array Bool
 {-# INLINE toPrimArrPA_Bool #-}
-toPrimArrPA_Bool (PBool _ ns# _ _ _) = toBoolPA# ns#
+toPrimArrPA_Bool (PBool sel _ _ _ _ _) = U.pick sel 1
 
 truesPA# :: PArray Bool -> Int#
 {-# INLINE_PA truesPA# #-}
 truesPA# (PBool _ _ _ fs ts) = lengthPA# dPA_Void ts
+-}
 
 {-
 data instance PArray Bool = PBool Int# PArray_Int# PArray_Int#
@@ -485,18 +480,22 @@ dPA_PArray :: PA a -> PA (PArray a)
 {-# INLINE_PA dPA_PArray #-}
 dPA_PArray pa
   = PA {
-      toPRepr      = toArrPRepr pa
-    , fromPRepr    = fromArrPRepr pa
+      toPRepr      = toPArrayPRepr pa
+    , fromPRepr    = fromPArrayPRepr pa
     , toArrPRepr   = toNestedPRepr pa
     , fromArrPRepr = fromNestedPRepr pa
     , dictPRepr    = dPR_PArray (dictPRepr pa)
     }
 
+{-# INLINE toPArrayPRepr #-}
+toPArrayPRepr pa (PArray n# xs) = PArray n# (toArrPRepr pa xs)
+
+{-# INLINE fromPArrayPRepr #-}
+fromPArrayPRepr pa (PArray n# xs) = PArray n# (fromArrPRepr pa xs)
+
 {-# INLINE toNestedPRepr #-}
-toNestedPRepr pa (PNested n# lens is xs)
-  = PNested n# lens is (toArrPRepr pa xs)
+toNestedPRepr pa (PNested segd xs) = PNested segd (toArrPRepr pa xs)
 
 {-# INLINE fromNestedPRepr #-}
-fromNestedPRepr pa (PNested n# lens is xs)
-  = PNested n# lens is (fromArrPRepr pa xs)
+fromNestedPRepr pa (PNested segd xs) = PNested segd (fromArrPRepr pa xs)
 
index d920d23..184c541 100644 (file)
@@ -3,23 +3,33 @@
 #include "fusion-phases.h"
 
 module Data.Array.Parallel.Lifted.PArray (
-  PArray,
+  PArray(..), PData,
 
   PA(..),
-  lengthPA#, replicatePA#, replicatelPA#, repeatPA#, emptyPA,
-  indexPA#, extractPA#, bpermutePA#, appPA#, applPA#,
+  lengthPA#, dataPA#, replicatePA#, replicatelPA#, repeatPA#, repeatcPA#,
+  emptyPA, indexPA#, extractPA#, bpermutePA#, appPA#, applPA#,
   packPA#, combine2PA#, fromListPA#, fromListPA, nfPA,
 
-  PRepr, PR(..), mkPR, mkReprPA
+  replicatePD, replicatelPD, repeatPD, repeatcPD, emptyPD,
+  indexPD, extractPD, bpermutePD, appPD, applPD,
+  packPD, combine2PD, fromListPD, fromListPD, nfPD,
+
+  PRepr, PR(..), mkPR, mkReprPA,
+
+  T_replicatePR, T_replicatelPR, T_repeatPR, T_repeatcPR, T_emptyPR,
+  T_indexPR, T_extractPR, T_bpermutePR, T_appPR, T_applPR,
+  T_packPR, T_combine2PR, T_fromListPR, T_fromListPR, T_nfPR
 ) where
 
 import qualified Data.Array.Parallel.Unlifted as U
-import Data.Array.Parallel.Lifted.Unboxed ( Segd, PArray_Int#, PArray_Bool# )
-import GHC.Exts (Int#, Int(..))
+import Data.Array.Parallel.Lifted.Selector
+import Data.Array.Parallel.Lifted.Unboxed ( elementsSegd# )
+import GHC.Exts (Int#, Int(..), (+#), (*#))
 
 -- |Lifted parallel arrays
 --
-data family PArray a
+data PArray a = PArray Int# (PData a)
+data family PData a
 
 -- |Representation types
 --
@@ -29,88 +39,222 @@ type family PRepr a
 --
 
 data PA a = PA {
-              toPRepr      :: a                -> PRepr a
-            , fromPRepr    :: PRepr a          -> a
-            , toArrPRepr   :: PArray a         -> PArray (PRepr a)
-            , fromArrPRepr :: PArray (PRepr a) -> PArray a
+              toPRepr      :: a               -> PRepr a
+            , fromPRepr    :: PRepr a         -> a
+            , toArrPRepr   :: PData a         -> PData (PRepr a)
+            , fromArrPRepr :: PData (PRepr a) -> PData a
             , dictPRepr    :: PR (PRepr a)
             }
 
-lengthPA# :: PA a -> PArray a -> Int#
+
+type T_emptyPR      a =  PData a
+
+type T_replicatePR  a =  Int# -> a -> PData a
+
+type T_replicatelPR a =  U.Segd            -- segd of result array
+                      -> PData a -> PData a
+
+type T_repeatPR     a =  Int#              -- number of times to repeat
+                      -> Int#              -- length of src array
+                      -> PData a -> PData a
+
+type T_repeatcPR    a =  Int#              -- length of result array
+                      -> U.Array Int       -- number of times each segment
+                                           -- is repeated
+                      -> U.Segd            -- src segd
+                      -> PData a -> PData a
+
+type T_indexPR      a =  PData a -> Int# -> a
+
+type T_extractPR    a =  PData a
+                      -> Int#              -- starting index
+                      -> Int#              -- length of result array
+                      -> PData a
+
+type T_bpermutePR   a =  PData a
+                      -> Int#              -- result length
+                      -> U.Array Int       -- indices
+                      -> PData a
+
+type T_appPR        a = PData a -> PData a -> PData a
+
+type T_applPR       a =  U.Segd -> PData a   -- src segd/data 1
+                      -> U.Segd -> PData a   -- src segd/data 2
+                      -> PData a
+
+type T_packPR       a =  PData a
+                      -> Int#              -- result length
+                      -> U.Array Bool      -- flags
+                      -> PData a
+
+type T_combine2PR   a =  Int#              -- result length
+                      -> Sel2              -- selector
+                      -> PData a -> PData a -> PData a
+
+type T_fromListPR a = Int# -> [a] -> PData a
+
+type T_nfPR a = PData a -> ()
+
+data PR a = PR {
+              emptyPR      :: T_emptyPR a
+            , replicatePR  :: T_replicatePR a
+            , replicatelPR :: T_replicatelPR a
+            , repeatPR     :: T_repeatPR a
+            , repeatcPR    :: T_repeatcPR a
+            , indexPR      :: T_indexPR a
+            , extractPR    :: T_extractPR a
+            , bpermutePR   :: T_bpermutePR a
+            , appPR        :: T_appPR a
+            , applPR       :: T_applPR a
+            , packPR       :: T_packPR a
+            , combine2PR   :: T_combine2PR a
+            , fromListPR   :: T_fromListPR a
+            , nfPR         :: T_nfPR a
+            }
+
+emptyPD :: PA a -> T_emptyPR a
+{-# INLINE_PA emptyPD #-}
+emptyPD pa = fromArrPRepr pa
+          $ emptyPR (dictPRepr pa)
+
+replicatePD :: PA a -> T_replicatePR a
+{-# INLINE_PA replicatePD #-}
+replicatePD pa n# x = fromArrPRepr pa
+                    . replicatePR (dictPRepr pa) n#
+                    $ toPRepr pa x
+
+replicatelPD :: PA a -> T_replicatelPR a
+{-# INLINE_PA replicatelPD #-}
+replicatelPD pa segd xs = fromArrPRepr pa
+                        . replicatelPR (dictPRepr pa) segd
+                        $ toArrPRepr pa xs
+    
+repeatPD :: PA a -> T_repeatPR a
+{-# INLINE_PA repeatPD #-}
+repeatPD pa n# len# xs = fromArrPRepr pa
+                       . repeatPR (dictPRepr pa) n# len#
+                       $ toArrPRepr pa xs
+
+repeatcPD :: PA a -> T_repeatcPR a
+{-# INLINE_PA repeatcPD #-}
+repeatcPD pa n# ns segd xs = fromArrPRepr pa
+                           . repeatcPR (dictPRepr pa) n# ns segd
+                           $ toArrPRepr pa xs
+
+indexPD :: PA a -> T_indexPR a
+{-# INLINE_PA indexPD #-}
+indexPD pa xs i# = fromPRepr pa
+                 $ indexPR (dictPRepr pa) (toArrPRepr pa xs) i#
+
+extractPD :: PA a -> T_extractPR a
+{-# INLINE_PA extractPD #-}
+extractPD pa xs i# m# = fromArrPRepr pa
+                      $ extractPR (dictPRepr pa) (toArrPRepr pa xs) i# m#
+
+bpermutePD :: PA a -> T_bpermutePR a
+{-# INLINE bpermutePD #-}
+bpermutePD pa xs n# is = fromArrPRepr pa
+                       $ bpermutePR (dictPRepr pa) (toArrPRepr pa xs) n# is
+
+appPD :: PA a -> T_appPR a
+{-# INLINE_PA appPD #-}
+appPD pa xs ys = fromArrPRepr pa
+               $ appPR (dictPRepr pa) (toArrPRepr pa xs) (toArrPRepr pa ys)
+
+applPD :: PA a -> T_applPR a
+{-# INLINE_PA applPD #-}
+applPD pa is xs js ys = fromArrPRepr pa
+                      $ applPR (dictPRepr pa) is (toArrPRepr pa xs)
+                                              js (toArrPRepr pa ys)
+
+packPD :: PA a -> T_packPR a
+{-# INLINE_PA packPD #-}
+packPD pa xs n# bs = fromArrPRepr pa
+                   $ packPR (dictPRepr pa) (toArrPRepr pa xs) n# bs
+
+combine2PD :: PA a -> T_combine2PR a
+{-# INLINE_PA combine2PD #-}
+combine2PD pa n# sel as bs
+  = fromArrPRepr pa
+  $ combine2PR (dictPRepr pa) n# sel (toArrPRepr pa as)
+                                     (toArrPRepr pa bs)
+
+fromListPD :: PA a -> T_fromListPR a
+{-# INLINE_PA fromListPD #-}
+fromListPD pa n# xs = fromArrPRepr pa
+                    $ fromListPR (dictPRepr pa) n# (map (toPRepr pa) xs)
+
+nfPD :: PA a -> T_nfPR a
+{-# INLINE nfPD #-}
+nfPD pa xs = nfPR (dictPRepr pa) (toArrPRepr pa xs)
+
+
+
+
+lengthPA# :: PArray a -> Int#
 {-# INLINE_PA lengthPA# #-}
-lengthPA# pa x = lengthPR (dictPRepr pa) (toArrPRepr pa x)
+lengthPA# (PArray n# _) = n#
+
+dataPA# :: PArray a -> PData a
+{-# INLINE_PA dataPA# #-}
+dataPA# (PArray _ d) = d
 
 emptyPA :: PA a -> PArray a
 {-# INLINE_PA emptyPA #-}
-emptyPA pa = fromArrPRepr pa
-           $ emptyPR (dictPRepr pa)
+emptyPA pa = PArray 0# (emptyPD pa)
 
 replicatePA# :: PA a -> Int# -> a -> PArray a
 {-# INLINE_PA replicatePA# #-}
-replicatePA# pa n# = fromArrPRepr pa
-                   . replicatePR (dictPRepr pa) n#
-                   . toPRepr pa
+replicatePA# pa n# x = PArray n# (replicatePD pa n# x)
 
-replicatelPA# :: PA a -> Segd -> PArray a -> PArray a
+replicatelPA# :: PA a -> U.Segd -> PArray a -> PArray a
 {-# INLINE_PA replicatelPA# #-}
-replicatelPA# pa segd = fromArrPRepr pa
-                       . replicatelPR (dictPRepr pa) segd
-                       . toArrPRepr pa
+replicatelPA# pa segd (PArray n# xs)
+  = PArray (elementsSegd# segd) (replicatelPD pa segd xs)
 
-repeatPA# :: PA a -> Int# -> Int# -> PArray a -> PArray a
+repeatPA# :: PA a -> Int# -> PArray a -> PArray a
 {-# INLINE_PA repeatPA# #-}
-repeatPA# pa n# len# = fromArrPRepr pa
-                     . repeatPR (dictPRepr pa) n# len#
-                     . toArrPRepr pa
+repeatPA# pa m# (PArray n# xs) = PArray (m# *# n#) (repeatPD pa m# n# xs)
 
-repeatcPA# :: PA a -> Int# -> PArray_Int# -> Segd -> PArray a -> PArray a
+repeatcPA# :: PA a -> U.Array Int -> U.Segd -> PArray a -> PArray a
 {-# INLINE_PA repeatcPA# #-}
-repeatcPA# pa n# ns segd = fromArrPRepr pa
-                         . repeatcPR (dictPRepr pa) n# ns segd
-                         . toArrPRepr pa
+repeatcPA# pa ns segd (PArray n# xs)
+  = case U.sum (U.zipWith (*) ns (U.lengthsSegd segd)) of
+      I# m# -> PArray m# (repeatcPD pa m# ns segd xs)
 
 indexPA# :: PA a -> PArray a -> Int# -> a
 {-# INLINE_PA indexPA# #-}
-indexPA# pa xs i# = fromPRepr pa
-                  $ indexPR (dictPRepr pa) (toArrPRepr pa xs) i#
+indexPA# pa (PArray _ xs) i# = indexPD pa xs i#
 
 extractPA# :: PA a -> PArray a -> Int# -> Int# -> PArray a
 {-# INLINE_PA extractPA# #-}
-extractPA# pa xs i# n# = fromArrPRepr pa
-                       $ extractPR (dictPRepr pa) (toArrPRepr pa xs) i# n#
+extractPA# pa (PArray _ xs) i# n# = PArray n# (extractPD pa xs i# n#)
 
-bpermutePA# :: PA a -> Int# -> PArray a -> PArray_Int# -> PArray a
+bpermutePA# :: PA a -> PArray a -> Int# -> U.Array Int -> PArray a
 {-# INLINE bpermutePA# #-}
-bpermutePA# pa n# xs is = fromArrPRepr pa
-                        $ bpermutePR (dictPRepr pa) n# (toArrPRepr pa xs) is
+bpermutePA# pa (PArray _ xs) n# is = PArray n# (bpermutePD pa xs n# is)
 
 appPA# :: PA a -> PArray a -> PArray a -> PArray a
 {-# INLINE_PA appPA# #-}
-appPA# pa xs ys = fromArrPRepr pa
-                $ appPR (dictPRepr pa) (toArrPRepr pa xs) (toArrPRepr pa ys)
+appPA# pa (PArray m# xs) (PArray n# ys) = PArray (m# +# n#) (appPD pa xs ys)
 
-applPA# :: PA a -> Segd -> PArray a -> Segd -> PArray a -> PArray a
+applPA# :: PA a -> U.Segd -> PArray a -> U.Segd -> PArray a -> PArray a
 {-# INLINE_PA applPA# #-}
-applPA# pa is xs js ys = fromArrPRepr pa
-                       $ applPR (dictPRepr pa) is (toArrPRepr pa xs)
-                                               js (toArrPRepr pa ys)
+applPA# pa is (PArray m# xs) js (PArray n# ys)
+  = PArray (m# +# n#) (applPD pa is xs js ys)
 
-packPA# :: PA a -> PArray a -> Int# -> PArray_Bool# -> PArray a
+packPA# :: PA a -> PArray a -> Int# -> U.Array Bool -> PArray a
 {-# INLINE_PA packPA# #-}
-packPA# pa arr n# = fromArrPRepr pa
-                  . packPR (dictPRepr pa) (toArrPRepr pa arr) n#
+packPA# pa (PArray _ xs) n# bs = PArray n# (packPD pa xs n# bs)
 
-combine2PA# :: PA a -> Int# -> PArray_Int# -> PArray_Int#
-            -> PArray a -> PArray a -> PArray a
+combine2PA# :: PA a -> Int# -> Sel2 -> PArray a -> PArray a -> PArray a
 {-# INLINE_PA combine2PA# #-}
-combine2PA# pa n# sel# is# as bs
-  = fromArrPRepr pa
-  $ combine2PR (dictPRepr pa) n# sel# is# (toArrPRepr pa as) (toArrPRepr pa bs)
+combine2PA# pa n# sel (PArray _ as) (PArray _ bs)
+  = PArray n# (combine2PD pa n# sel as bs)
 
 fromListPA# :: PA a -> Int# -> [a] -> PArray a
 {-# INLINE_PA fromListPA# #-}
-fromListPA# pa n# xs = fromArrPRepr pa
-                     $ fromListPR (dictPRepr pa) n# (map (toPRepr pa) xs)
+fromListPA# pa n# xs = PArray n# (fromListPD pa n# xs)
 
 fromListPA :: PA a -> [a] -> PArray a
 {-# INLINE fromListPA #-}
@@ -119,44 +263,24 @@ fromListPA pa xs = case length xs of
 
 nfPA :: PA a -> PArray a -> ()
 {-# INLINE nfPA #-}
-nfPA pa xs = nfPR (dictPRepr pa) $ toArrPRepr pa xs
-
-data PR a = PR {
-              lengthPR     :: PArray a -> Int#
-            , emptyPR      :: PArray a
-            , replicatePR  :: Int# -> a -> PArray a
-            , replicatelPR :: Segd -> PArray a -> PArray a
-            , repeatPR     :: Int# -> Int# -> PArray a -> PArray a
-            , repeatcPR    :: Int# -> PArray_Int# -> Segd -> PArray a -> PArray a
-            , indexPR      :: PArray a -> Int# -> a
-            , extractPR    :: PArray a -> Int# -> Int# -> PArray a
-            , bpermutePR   :: Int# -> PArray a -> PArray_Int# -> PArray a
-            , appPR        :: PArray a -> PArray a -> PArray a
-            , applPR       :: Segd -> PArray a -> Segd -> PArray a -> PArray a
-            , packPR       :: PArray a -> Int# -> PArray_Bool# -> PArray a
-            , combine2PR   :: Int# -> PArray_Int# -> PArray_Int#
-                              -> PArray a -> PArray a -> PArray a
-            , fromListPR   :: Int# -> [a] -> PArray a
-            , nfPR         :: PArray a -> ()
-            }
+nfPA pa (PArray _ xs) = nfPD pa xs
 
 mkPR :: PA a -> PR a
 {-# INLINE mkPR #-}
 mkPR pa = PR {
-            lengthPR     = lengthPA# pa
-          , emptyPR      = emptyPA pa
-          , replicatePR  = replicatePA# pa
-          , replicatelPR = replicatelPA# pa
-          , repeatPR     = repeatPA# pa
-          , repeatcPR    = repeatcPA# pa
-          , indexPR      = indexPA# pa
-          , bpermutePR   = bpermutePA# pa
-          , appPR        = appPA# pa
-          , applPR       = applPA# pa
-          , packPR       = packPA# pa
-          , combine2PR   = combine2PA# pa
-          , fromListPR   = fromListPA# pa
-          , nfPR         = nfPA pa
+            emptyPR      = emptyPD pa
+          , replicatePR  = replicatePD pa
+          , replicatelPR = replicatelPD pa
+          , repeatPR     = repeatPD pa
+          , repeatcPR    = repeatcPD pa
+          , indexPR      = indexPD pa
+          , bpermutePR   = bpermutePD pa
+          , appPR        = appPD pa
+          , applPR       = applPD pa
+          , packPR       = packPD pa
+          , combine2PR   = combine2PD pa
+          , fromListPR   = fromListPD pa
+          , nfPR         = nfPD pa
           }
 
 mkReprPA :: (a ~ PRepr a) => PR a -> PA a
index 87b40ae..9311f38 100644 (file)
@@ -4,24 +4,27 @@
 #include "fusion-phases.h"
 
 module Data.Array.Parallel.Lifted.Repr (
-  PArray(..),
-  Void, void,
+  PData(..),
+  Void, void, pvoid, dPA_Void, dPR_Void,
+{-
   Wrap(..),
-  Enumeration(..),
   Sum2(..), Sum3(..), 
+-}
+
+  punit, dPR_Unit,
+  Wrap(..), dPR_Wrap,
 
-  dPA_Void,
-  dPR_Void, dPR_Unit, dPR_Wrap,
-  dPR_Enumeration,
   dPR_2, dPR_3, dPR_4, dPR_5, zipPA#, unzipPA#, zip3PA#,
-  dPR_Sum2, dPR_Sum3,
+  Sum2(..), {-Sum3(..),-} dPR_Sum2, {-dPR_Sum3,-}
 
-  dPR_PArray, nested_lengthPA, segdOfPA#, concatPA#,
+  dPR_PArray, segdPA#, concatPA#, segmentPA#, copySegdPA#
 ) where
 
 import Data.Array.Parallel.Lifted.PArray
-import Data.Array.Parallel.Lifted.Unboxed
+import Data.Array.Parallel.Lifted.Selector
+import Data.Array.Parallel.Lifted.Unboxed ( elementsSegd# )
 
+import qualified Data.Array.Parallel.Unlifted as U
 import Data.Array.Parallel.Base ((:*:)(..), fromBool)
 
 import qualified Data.List as L
@@ -29,7 +32,6 @@ import GHC.Exts  (Int#, Int(..), (+#), (-#), (*#))
 import Debug.Trace
 
 
-
 data Void
 
 traceFn   = flip const -- trace
@@ -38,13 +40,15 @@ traceArgs = flip  const -- trace
 void :: Void
 void = error "Data.Array.Parallel.void"
 
-data instance PArray Void = PVoid Int#
+data instance PData Void
+
+pvoid :: PData Void
+pvoid = error "Data.Array.Parallel.PData Void"
 
 dPR_Void :: PR Void
 {-# INLINE dPR_Void #-}
 dPR_Void = PR {
-             lengthPR     = lengthPR_Void
-           , emptyPR      = emptyPR_Void
+             emptyPR      = emptyPR_Void
            , replicatePR  = replicatePR_Void
            , replicatelPR = replicatelPR_Void
            , repeatPR     = repeatPR_Void
@@ -60,65 +64,61 @@ dPR_Void = PR {
            , nfPR         = nfPR_Void
            }
 
-{-# INLINE lengthPR_Void #-}
-lengthPR_Void (PVoid n#) = 
-              n#
-
+emptyPR_Void :: T_emptyPR Void
 {-# INLINE emptyPR_Void #-}
-emptyPR_Void = traceFn "emptyPR_Void" $
-             PVoid 0#
+emptyPR_Void = traceFn "emptyPR_Void" $ pvoid
 
+replicatePR_Void :: T_replicatePR Void
 {-# INLINE replicatePR_Void #-}
-replicatePR_Void n# _ = traceFn "replicatePR_Void" $
-                 PVoid n#
+replicatePR_Void _ _ = traceFn "replicatePR_Void" $ pvoid
 
+replicatelPR_Void :: T_replicatelPR Void
 {-# INLINE replicatelPR_Void #-}
-replicatelPR_Void segd _ = traceFn "replicatelPR_Void" $
-                  PVoid (elementsSegdPA# segd)
+replicatelPR_Void segd _ = traceFn "replicatelPR_Void" $ pvoid
 
+repeatPR_Void :: T_repeatPR Void
 {-# INLINE repeatPR_Void #-}
-repeatPR_Void n# len# (PVoid _) = traceFn "repeatPR_Void" $
-              PVoid (n# *# len#)
+repeatPR_Void _ _ _ = traceFn "repeatPR_Void" $ pvoid
 
+repeatcPR_Void :: T_repeatcPR Void
 {-# INLINE repeatcPR_Void #-}
-repeatcPR_Void n# _ _ (PVoid _) = traceFn "repeatcPR_Void" $
-              PVoid n#
+repeatcPR_Void _ _ _ _ = traceFn "repeatcPR_Void" $ pvoid
 
-indexPR_Void :: PArray Void -> Int# -> Void
+indexPR_Void :: T_indexPR Void
 {-# INLINE indexPR_Void #-}
-indexPR_Void (PVoid n#) i# = traceFn "indexPR_Void" $
-             void
+indexPR_Void _ _ = traceFn "indexPR_Void" $ void
 
-extractPR_Void :: PArray Void -> Int# -> Int# -> PArray Void
+extractPR_Void :: T_extractPR Void
 {-# INLINE extractPR_Void #-}
-extractPR_Void (PVoid _) i# n# = traceFn "extractPR_Void" $
-             PVoid n#
+extractPR_Void  _ _ _ = traceFn "extractPR_Void" $ pvoid
 
+bpermutePR_Void :: T_bpermutePR Void
 {-# INLINE bpermutePR_Void #-}
-bpermutePR_Void n# (PVoid _) _ = traceFn "bpermutePR_Void" $
-                PVoid n#
+bpermutePR_Void _ _ _ = traceFn "bpermutePR_Void" $ pvoid
 
+appPR_Void :: T_appPR Void
 {-# INLINE appPR_Void #-}
-appPR_Void (PVoid m#) (PVoid n#) = traceFn "appPR_Void" $
-           PVoid (m# +# n#)
+appPR_Void  _ _ = traceFn "appPR_Void" $ pvoid
 
+applPR_Void :: T_applPR Void
 {-# INLINE applPR_Void #-}
-applPR_Void _ (PVoid m#) _ (PVoid n#) = traceFn "applPR_Void" $
-            PVoid (m# +# n#)
+applPR_Void _ _ _ _ = traceFn "applPR_Void" $ pvoid
 
+packPR_Void :: T_packPR Void
 {-# INLINE packPR_Void #-}
-packPR_Void (PVoid _) n# _ = traceFn "packPR_Void" $
-            PVoid n#
+packPR_Void _ _ _ = traceFn "packPR_Void" $ pvoid
 
+combine2PR_Void :: T_combine2PR Void
 {-# INLINE combine2PR_Void #-}
-combine2PR_Void n# _ _ (PVoid _) (PVoid _) = traceFn "combine2PR_Void" $
-                PVoid n#
+combine2PR_Void _ _ _ _ = traceFn "combine2PR_Void" $ pvoid
 
+fromListPR_Void :: T_fromListPR Void
 {-# INLINE fromListPR_Void #-}
-fromListPR_Void n# _ = PVoid n#
+fromListPR_Void _ _ = pvoid
 
+nfPR_Void :: T_nfPR Void
 {-# INLINE nfPR_Void #-}
-nfPR_Void (PVoid _) = ()
+nfPR_Void _ = ()
 
 type instance PRepr Void = Void
 
@@ -132,13 +132,17 @@ dPA_Void = PA {
            , dictPRepr    = dPR_Void
            }
 
-data instance PArray () = PUnit Int# ()
+
+
+data instance PData () = PUnit
+
+punit :: PData ()
+punit = PUnit
 
 dPR_Unit :: PR ()
 {-# INLINE dPR_Unit #-}
 dPR_Unit = PR {
-             lengthPR     = lengthPR_Unit
-           , emptyPR      = emptyPR_Unit
+             emptyPR      = emptyPR_Unit
            , replicatePR  = replicatePR_Unit
            , replicatelPR = replicatelPR_Unit
            , repeatPR     = repeatPR_Unit
@@ -153,81 +157,76 @@ dPR_Unit = PR {
            , fromListPR   = fromListPR_Unit
            , nfPR         = nfPR_Unit
            }
-         
-
-{-# INLINE lengthPR_Unit #-}
-lengthPR_Unit (PUnit n# _) = 
-              n#
 
+emptyPR_Unit :: T_emptyPR ()         
 {-# INLINE emptyPR_Unit #-}
-emptyPR_Unit = traceFn "emptyPR_Unit" $
-             PUnit 0# ()
+emptyPR_Unit = traceFn "emptyPR_Unit" $ PUnit
 
+replicatePR_Unit :: T_replicatePR ()
 {-# INLINE replicatePR_Unit #-}
-replicatePR_Unit n# u = 
+replicatePR_Unit n# () = 
   traceFn "replicatePR_Unit" $
   traceArgs ("replicatePR_Unit len = " ++ show (I# n#)) $
-                 PUnit n# u
+  PUnit
 
+replicatelPR_Unit :: T_replicatelPR ()
 {-# INLINE replicatelPR_Unit #-}
-replicatelPR_Unit segd (PUnit _ u) = 
+replicatelPR_Unit segd u =
   traceFn "replicatelPR_Unit" 
-  traceArgs ("replicatelPR_Unit args len = " ++ (show (I# (elementsSegdPA# segd))))$
-  PUnit (elementsSegdPA# segd) u
+  traceArgs ("replicatelPR_Unit args len = " ++ (show (U.elementsSegd segd))) $
+  u
 
+repeatPR_Unit :: T_repeatPR ()
 {-# INLINE repeatPR_Unit #-}
-repeatPR_Unit n# len# (PUnit _ u) = traceFn "repeatPR_Unit" $
-              PUnit (n# *# len#) u
+repeatPR_Unit _ _ u = traceFn "repeatPR_Unit" $ u
 
+repeatcPR_Unit :: T_repeatcPR ()
 {-# INLINE repeatcPR_Unit #-}
-repeatcPR_Unit n# _ _ (PUnit _ u) = traceFn "repeatcPR_Unit" $
-              PUnit n# u
+repeatcPR_Unit _ _ _ u = traceFn "repeatcPR_Unit" $ u
 
-indexPR_Unit :: PArray () -> Int# -> ()
+indexPR_Unit :: T_indexPR ()
 {-# INLINE indexPR_Unit #-}
-indexPR_Unit (PUnit n# u) i# = traceFn "indexPR_Unit" $
-             u
+indexPR_Unit PUnit _ = traceFn "indexPR_Unit" $ ()
 
-extractPR_Unit :: PArray () -> Int# -> Int# -> PArray ()
+extractPR_Unit :: T_extractPR ()
 {-# INLINE extractPR_Unit #-}
-extractPR_Unit (PUnit _ u) _ n# = traceFn "extractPR_Unit" $
-             PUnit n# u
+extractPR_Unit u _ _ = traceFn "extractPR_Unit" $ u
 
+bpermutePR_Unit :: T_bpermutePR ()
 {-# INLINE bpermutePR_Unit #-}
-bpermutePR_Unit n# (PUnit _ u) _ = traceFn "bpermutePR_Unit" $
-                PUnit n# u
+bpermutePR_Unit u _ _ = traceFn "bpermutePR_Unit" $ u
 
+appPR_Unit :: T_appPR ()
 {-# INLINE appPR_Unit #-}
-appPR_Unit (PUnit m# u) (PUnit n# v) = traceFn "appPR_Unit" $
-           PUnit (m# +# n#) (u `seq` v)
+appPR_Unit u v = traceFn "appPR_Unit" (u `seq` v)
 
+applPR_Unit :: T_applPR ()
 {-# INLINE applPR_Unit #-}
-applPR_Unit _ (PUnit m# u) _ (PUnit n# v) = traceFn "applPR_Unit" $
-            PUnit (m# +# n#) (u `seq` v)
+applPR_Unit _ u _ v = traceFn "applPR_Unit" (u `seq` v)
 
+packPR_Unit :: T_packPR ()
 {-# INLINE packPR_Unit #-}
-packPR_Unit (PUnit _ u) n# _ = traceFn "packPR_Unit" $
-            PUnit n# u
+packPR_Unit u _ _ = traceFn "packPR_Unit" $ u
 
+combine2PR_Unit :: T_combine2PR ()
 {-# INLINE combine2PR_Unit #-}
-combine2PR_Unit n# _ _ (PUnit _ u1) (PUnit _ u2) = traceFn "combine2PR_Unit" $
-  PUnit n# (u1 `seq` u2)
+combine2PR_Unit _ _ u v = traceFn "combine2PR_Unit" (u `seq` v)
 
+fromListPR_Unit :: T_fromListPR ()
 {-# INLINE fromListPR_Unit #-}
-fromListPR_Unit n# xs = PUnit n# (foldr seq () xs)
+fromListPR_Unit _ xs = foldr seq PUnit xs
 
 {-# INLINE nfPR_Unit #-}
-nfPR_Unit (PUnit _ u) = u
+nfPR_Unit PUnit = ()
 
 data Wrap a = Wrap a
 
-data instance PArray (Wrap a) = PWrap Int# (PArray a)
+data instance PData (Wrap a) = PWrap (PData a)
 
 dPR_Wrap :: PR a -> PR (Wrap a)
 {-# INLINE dPR_Wrap #-}
 dPR_Wrap pr = PR {
-              lengthPR     = lengthPR_Wrap
-            , emptyPR      = emptyPR_Wrap pr
+              emptyPR      = emptyPR_Wrap pr
             , replicatePR  = replicatePR_Wrap pr
             , replicatelPR = replicatelPR_Wrap pr
             , repeatPR     = repeatPR_Wrap pr
@@ -238,115 +237,79 @@ dPR_Wrap pr = PR {
             , appPR        = appPR_Wrap pr
             , applPR       = applPR_Wrap pr
             , packPR       = packPR_Wrap pr
-            , combine2PR   = combine2PR_Wrap pr
             }
 
-{-# INLINE lengthPR_Wrap #-}
-lengthPR_Wrap (PWrap n# _) = 
-              n#
-
 {-# INLINE emptyPR_Wrap #-}
-emptyPR_Wrap pr = traceFn "emptyPR_Wrap" $
-             PWrap 0# (emptyPR pr)
+emptyPR_Wrap pr = traceFn "emptyPR_Wrap" $ PWrap (emptyPR pr)
 
 {-# INLINE replicatePR_Wrap #-}
-replicatePR_Wrap pr n# ~(Wrap x) = traceFn "replicatePR_Wrap" $
-                 PWrap n# (replicatePR pr n# x)
+replicatePR_Wrap pr n# (Wrap x) = traceFn "replicatePR_Wrap" $
+                 PWrap (replicatePR pr n# x)
 
 {-# INLINE replicatelPR_Wrap #-}
-replicatelPR_Wrap pr segd (PWrap xs) = traceFn "replicatelPR_Wrap" $
-                  PWrap (elementsSegdPA# segd) (replicatelPR pr segd xs)
+replicatelPR_Wrap pr segd (PWrap xs) = traceFn "replicatelPR_Wrap" $
+                  PWrap (replicatelPR pr segd xs)
 
 {-# INLINE repeatPR_Wrap #-}
-repeatPR_Wrap pr n# len# (PWrap xs) = traceFn "repeatPR_Wrap" $
-              PWrap (n# *# len#) (repeatPR pr n# len# xs)
+repeatPR_Wrap pr n# len# (PWrap xs) = traceFn "repeatPR_Wrap" $
+              PWrap (repeatPR pr n# len# xs)
 
 {-# INLINE repeatcPR_Wrap #-}
-repeatcPR_Wrap pr n# is segd (PWrap xs) = traceFn "repeatcPR_Wrap" $
-              PWrap n# (repeatcPR pr n# is segd xs)
+repeatcPR_Wrap pr n# is segd (PWrap xs) = traceFn "repeatcPR_Wrap" $
+              PWrap (repeatcPR pr n# is segd xs)
 
 {-# INLINE indexPR_Wrap #-}
-indexPR_Wrap pr (PWrap n# xs) i# = traceFn "indexPR_Wrap" $
+indexPR_Wrap pr (PWrap xs) i# = traceFn "indexPR_Wrap" $
              Wrap (indexPR pr xs i#)
 
 {-# INLINE extractPR_Wrap #-}
-extractPR_Wrap pr (PWrap xs) i# n# = traceFn "extractPR_Wrap" $
-             PWrap n# (extractPR pr xs i# n#)
+extractPR_Wrap pr (PWrap xs) i# n# = traceFn "extractPR_Wrap" $
+             PWrap (extractPR pr xs i# n#)
 
 {-# INLINE bpermutePR_Wrap #-}
-bpermutePR_Wrap pr n# (PWrap _ xs) is = traceFn "bpermutePR_Wrap" $
-                PWrap n# (bpermutePR pr n# xs is)
+bpermutePR_Wrap pr (PWrap xs) n# is = traceFn "bpermutePR_Wrap" $
+                PWrap (bpermutePR pr xs n# is)
 
 {-# INLINE appPR_Wrap #-}
-appPR_Wrap pr (PWrap m# xs) (PWrap n# ys) = traceFn "appPR_Wrap" $
-           PWrap (m# +# n#) (appPR pr xs ys)
+appPR_Wrap pr (PWrap xs) (PWrap ys) = traceFn "appPR_Wrap" $
+           PWrap (appPR pr xs ys)
 
 {-# INLINE applPR_Wrap #-}
-applPR_Wrap pr is (PWrap m# xs) js (PWrap n# ys) = traceFn "applPR_Wrap" $
-            PWrap (m# +# n#) (applPR pr is xs js ys)
+applPR_Wrap pr is (PWrap xs) js (PWrap ys) = traceFn "applPR_Wrap" $
+            PWrap (applPR pr is xs js ys)
 
 {-# INLINE packPR_Wrap #-}
-packPR_Wrap pr (PWrap _ xs) n# sel# = traceFn "packPR_Wrap" $
-            PWrap n# (packPR pr xs n# sel#)
-
-combine2PR_Wrap:: PR a -> Int# -> PArray_Int# -> PArray_Int#
-                              -> PArray (Wrap a) -> PArray (Wrap a) -> PArray (Wrap a)
-combine2PR_Wrap _ _ _ _ _ = traceFn "combine2PR_Wrap" $
-                error "combine2PR_Wrap nyi"
-
-data Enumeration = Enumeration Int#
-
-data instance PArray Enumeration = PEnum Int# PArray_Int# PArray_Int#
-
-dPR_Enumeration :: PR Enumeration
-{-# INLINE dPR_Enumeration #-}
-dPR_Enumeration = PR {
-                    lengthPR    = lengthPR_Enumeration
-                  , emptyPR     = emptyPR_Enumeration
-                  , replicatePR = replicatePR_Enumeration
-                  }
-
-{-# INLINE lengthPR_Enumeration #-}
-lengthPR_Enumeration (PEnum n# _ _) = n#
-
-{-# INLINE emptyPR_Enumeration #-}
-emptyPR_Enumeration = traceFn "emptyPR_Enumeration" $
-                    PEnum 0# emptyPA_Int# emptyPA_Int#
-
-{-# INLINE replicatePR_Enumeration #-}
-replicatePR_Enumeration n# enum
-  = traceFn "replicatePR_Enumeration" $
-      PEnum n# (replicatePA_Int# n# (case enum of { Enumeration i# -> i# }))
-             (upToPA_Int# n#)
-
-data instance PArray (a,b)
-  = P_2 Int# (PArray a)
-             (PArray b)
-
-data instance PArray (a,b,c)
-  = P_3 Int# (PArray a)
-             (PArray b)
-             (PArray c)
-
-data instance PArray (a,b,c,d)
-  = P_4 Int# (PArray a)
-             (PArray b)
-             (PArray c)
-             (PArray d)
-
-data instance PArray (a,b,c,d,e)
-  = P_5 Int# (PArray a)
-             (PArray b)
-             (PArray c)
-             (PArray d)
-             (PArray e)
+packPR_Wrap pr (PWrap xs) n# sel# = traceFn "packPR_Wrap" $
+            PWrap (packPR pr xs n# sel#)
+
+
+data instance PData (a,b)
+  = P_2 (PData a)
+        (PData b)
+
+data instance PData (a,b,c)
+  = P_3 (PData a)
+        (PData b)
+        (PData c)
+
+data instance PData (a,b,c,d)
+  = P_4 (PData a)
+        (PData b)
+        (PData c)
+        (PData d)
+
+data instance PData (a,b,c,d,e)
+  = P_5 (PData a)
+        (PData b)
+        (PData c)
+        (PData d)
+        (PData e)
 
 dPR_2 :: PR a -> PR b -> PR (a,b)
 {-# INLINE dPR_2 #-}
 dPR_2 pra prb
   = PR {
-      lengthPR     = lengthPR_2
-    , emptyPR      = emptyPR_2 pra prb
+      emptyPR      = emptyPR_2 pra prb
     , replicatePR  = replicatePR_2 pra prb
     , replicatelPR = replicatelPR_2 pra prb
     , repeatPR     = repeatPR_2 pra prb
@@ -362,104 +325,94 @@ dPR_2 pra prb
     , nfPR         = nfPR_2 pra prb
     }
 
-{-# INLINE lengthPR_2 #-}
-lengthPR_2 (P_2 n# _ _) = n#
-
 {-# INLINE emptyPR_2 #-}
 emptyPR_2 pra prb = traceFn "emptyPR_2" $
-          P_2 0# (emptyPR pra) (emptyPR prb)
+          P_2 (emptyPR pra) (emptyPR prb)
 
 {-# INLINE replicatePR_2 #-}
-replicatePR_2 pra prb n# ~(a,b) = 
+replicatePR_2 pra prb n# (a,b) = 
   traceFn "replicatePR_2" $
   traceArgs ("replicatePR_2 args len = "  ++ (show (I# n#))) $
-  P_2 n# (replicatePR pra n# a)
-           (replicatePR prb n# b)
+  P_2 (replicatePR pra n# a)
+      (replicatePR prb n# b)
 
 {-# INLINE replicatelPR_2 #-}
-replicatelPR_2 pra prb segd (P_2 as bs)
+replicatelPR_2 pra prb segd (P_2 as bs)
   = traceFn "replicatelPR_2" $
-  P_2 (elementsSegdPA# segd) (replicatelPR pra segd as)
-                             (replicatelPR prb segd bs) 
+  P_2 (replicatelPR pra segd as)
+      (replicatelPR prb segd bs) 
 
 {-# INLINE repeatPR_2 #-}
-repeatPR_2 pra prb n# len# (P_2 as bs)
+repeatPR_2 pra prb n# len# (P_2 as bs)
   = traceFn "repeatPR_2" $
-  P_2 (n# *# len#) (repeatPR pra n# len# as)
-                   (repeatPR prb n# len# bs)
+  P_2 (repeatPR pra n# len# as)
+      (repeatPR prb n# len# bs)
 
 {-# INLINE repeatcPR_2 #-}
-repeatcPR_2 pra prb n# ns segd (P_2 as bs)
+repeatcPR_2 pra prb n# ns segd (P_2 as bs)
   = traceFn "repeatcPR_2" $
-  P_2 n# (repeatcPR pra n# ns segd as)
-         (repeatcPR prb n# ns segd bs)
+  P_2 (repeatcPR pra n# ns segd as)
+      (repeatcPR prb n# ns segd bs)
 
 {-# INLINE indexPR_2 #-}
-indexPR_2 pra prb (P_2 as bs) i# = traceFn "indexPR_2" $
+indexPR_2 pra prb (P_2 as bs) i# = traceFn "indexPR_2" $
           (indexPR pra as i#, indexPR prb bs i#)
 
 {-# INLINE extractPR_2 #-}
-extractPR_2 pra prb (P_2 as bs) i# n# = traceFn "extractPR_2" $
-          P_2 n# (extractPR pra as i# n#)
-                 (extractPR prb bs i# n#)
+extractPR_2 pra prb (P_2 as bs) i# n# = traceFn "extractPR_2" $
+          P_2 (extractPR pra as i# n#)
+              (extractPR prb bs i# n#)
 
 {-# INLINE bpermutePR_2 #-}
-bpermutePR_2 pra prb n# (P_2 _ as bs) is
+bpermutePR_2 pra prb (P_2 as bs) n# is
   = traceFn "bpermutePR_2" $
-  P_2 n# (bpermutePR pra n# as is) (bpermutePR prb n# bs is)
+  P_2 (bpermutePR pra as n# is) (bpermutePR prb bs n# is)
 
 {-# INLINE appPR_2 #-}
-appPR_2 pra prb (P_2 m# as1 bs1) (P_2 n# as2 bs2)
-  = P_2 (m# +# n#) (appPR pra as1 as2) (appPR prb bs1 bs2)
+appPR_2 pra prb (P_2 as1 bs1) (P_2 as2 bs2)
+  = P_2 (appPR pra as1 as2) (appPR prb bs1 bs2)
 
 {-# INLINE applPR_2 #-}
-applPR_2 pra prb is (P_2 m# as1 bs1) js (P_2 n# as2 bs2)
+applPR_2 pra prb is (P_2 as1 bs1) js (P_2 as2 bs2)
   = traceFn "applPR_2" $
-  P_2 (m# +# n#) (applPR pra is as1 js as2)
-                   (applPR prb is bs1 js bs2)
+  P_2 (applPR pra is as1 js as2)
+      (applPR prb is bs1 js bs2)
 
 {-# INLINE packPR_2 #-}
-packPR_2 pra prb (P_2 as bs) n# sel# = traceFn "packPR_2" $
-         P_2 n# (packPR pra as n# sel#)
-                                                (packPR prb bs n# sel#)
+packPR_2 pra prb (P_2 as bs) n# sel# = traceFn "packPR_2" $
+         P_2 (packPR pra as n# sel#)
+             (packPR prb bs n# sel#)
 
 {-# INLINE combine2PR_2 #-}
-combine2PR_2 pra prb n# sel# is# (P_2 _ as1 bs1) (P_2 _ as2 bs2)
+combine2PR_2 pra prb n# sel (P_2 as1 bs1) (P_2 as2 bs2)
   = traceFn "combine2PR_2" $
-       P_2 n# (combine2PR pra n# sel# is# as1 as2)
-              (combine2PR prb n# sel# is# bs1 bs2)
+       P_2 (combine2PR pra n# sel as1 as2)
+           (combine2PR prb n# sel bs1 bs2)
 
 {-# INLINE fromListPR_2 #-}
 fromListPR_2 pra prb n# xs
-  = P_2 n# (fromListPR pra n# as)
-           (fromListPR prb n# bs)
+  = P_2 (fromListPR pra n# as)
+        (fromListPR prb n# bs)
   where
     (as,bs) = unzip xs
 
 {-# INLINE nfPR_2 #-}
-nfPR_2 pra prb (P_2 as bs)
+nfPR_2 pra prb (P_2 as bs)
   = nfPR pra as `seq` nfPR prb bs
 
-zipPA# :: PA a -> PA b -> PArray a -> PArray b -> PArray (a,b)
+zipPA# :: PArray a -> PArray b -> PArray (a,b)
 {-# INLINE_PA zipPA# #-}
-zipPA# pa pb xs ys = 
-  traceFn "zipPA" $ 
-  traceArgs  ("zipPA args len1:" ++ show (I# (lengthPA# pa xs)) ++
-               "\nlen2:" ++ show (I# (lengthPA# pb ys))
-    ) $
-       P_2 (lengthPA# pa xs) xs ys
-
-unzipPA# :: PA a -> PA b  -> PArray (a,b) -> (PArray a,  PArray b)
+zipPA# (PArray n# xs) (PArray _ ys) = PArray n# (P_2 xs ys)
+
+unzipPA# :: PArray (a,b) -> (PArray a, PArray b)
 {-# INLINE_PA unzipPA# #-}
-unzipPA# pa pb (P_2 n xs ys)  = traceFn "unzipPA" $
-         (xs, ys)
+unzipPA# (PArray n# (P_2 xs ys)) = (PArray n# xs, PArray n# ys)
 
 dPR_3 :: PR a -> PR b -> PR c -> PR (a,b,c)
 {-# INLINE dPR_3 #-}
 dPR_3 pra prb prc
   = PR {
-      lengthPR     = lengthPR_3
-    , emptyPR      = emptyPR_3 pra prb prc
+      emptyPR      = emptyPR_3 pra prb prc
     , replicatePR  = replicatePR_3 pra prb prc
     , replicatelPR = replicatelPR_3 pra prb prc
     , repeatPR     = repeatPR_3 pra prb prc
@@ -475,112 +428,108 @@ dPR_3 pra prb prc
     , nfPR         = nfPR_3 pra prb prc
     }
 
-{-# INLINE lengthPR_3 #-}
-lengthPR_3 (P_3 n# _ _ _) = n#
-
 {-# INLINE emptyPR_3 #-}
 emptyPR_3 pra prb prc = traceFn "emptyPR_3" $
-          P_3 0# (emptyPR pra) (emptyPR prb) (emptyPR prc)
+          P_3 (emptyPR pra) (emptyPR prb) (emptyPR prc)
 
 {-# INLINE replicatePR_3 #-}
-replicatePR_3 pra prb prc n# ~(a,b,c)
+replicatePR_3 pra prb prc n# (a,b,c)
   = traceFn "replicatePR_3" $
-  P_3 n# (replicatePR pra n# a)
-           (replicatePR prb n# b)
-           (replicatePR prc n# c)
+  P_3 (replicatePR pra n# a)
+      (replicatePR prb n# b)
+      (replicatePR prc n# c)
 
 {-# INLINE replicatelPR_3 #-}
-replicatelPR_3 pra prb prc segd (P_3 as bs cs)
+replicatelPR_3 pra prb prc segd (P_3 as bs cs)
   = traceFn "replicatelPR_3" $
-  P_3 (elementsSegdPA# segd) (replicatelPR pra segd as)
-                             (replicatelPR prb segd bs)
-                             (replicatelPR prc segd cs)
+  P_3 (replicatelPR pra segd as)
+      (replicatelPR prb segd bs)
+      (replicatelPR prc segd cs)
 
 {-# INLINE repeatPR_3 #-}
-repeatPR_3 pra prb prc n# len# (P_3 as bs cs)
+repeatPR_3 pra prb prc n# len# (P_3 as bs cs)
   = traceFn "repeatPR_3" $
-  P_3 (n# *# len#) (repeatPR pra n# len# as)
-                   (repeatPR prb n# len# bs)
-                   (repeatPR prc n# len# cs)
+  P_3 (repeatPR pra n# len# as)
+      (repeatPR prb n# len# bs)
+      (repeatPR prc n# len# cs)
 
 {-# INLINE repeatcPR_3 #-}
-repeatcPR_3 pra prb prc n# ns segd (P_3 as bs cs)
+repeatcPR_3 pra prb prc n# ns segd (P_3 as bs cs)
   = traceFn "repeatcPR_3" $
-  P_3 n# (repeatcPR pra n# ns segd as)
-         (repeatcPR prb n# ns segd bs)
-         (repeatcPR prc n# ns segd cs)
+  P_3 (repeatcPR pra n# ns segd as)
+      (repeatcPR prb n# ns segd bs)
+      (repeatcPR prc n# ns segd cs)
 
 {-# INLINE indexPR_3 #-}
-indexPR_3 pra prb prc (P_3 n# as bs cs) i#
+indexPR_3 pra prb prc (P_3 as bs cs) i#
   = traceFn "indexPR_3" $
   (indexPR pra as i#, indexPR prb bs i#, indexPR prc cs i#)
 
 {-# INLINE extractPR_3 #-}
-extractPR_3 pra prb prc (P_3 as bs cs) i# n# = traceFn "extractPR_3" $
-          P_3 n# (extractPR pra as i# n#)
-                 (extractPR prb bs i# n#)
-                 (extractPR prc cs i# n#)
+extractPR_3 pra prb prc (P_3 as bs cs) i# n# = traceFn "extractPR_3" $
+          P_3 (extractPR pra as i# n#)
+              (extractPR prb bs i# n#)
+              (extractPR prc cs i# n#)
 
 {-# INLINE bpermutePR_3 #-}
-bpermutePR_3 pra prb prc n# (P_3 _ as bs cs) is
+bpermutePR_3 pra prb prc (P_3 as bs cs) n# is
   = traceFn "bpermutePR_3" $
-  P_3 n# (bpermutePR pra n# as is)
-         (bpermutePR prb n# bs is)
-         (bpermutePR prc n# cs is)
+  P_3 (bpermutePR pra as n# is)
+      (bpermutePR prb bs n# is)
+      (bpermutePR prc cs n# is)
 
 {-# INLINE appPR_3 #-}
-appPR_3 pra prb prc (P_3 m# as1 bs1 cs1) (P_3 n# as2 bs2 cs2)
+appPR_3 pra prb prc (P_3 as1 bs1 cs1) (P_3 as2 bs2 cs2)
   = traceFn "appPR_3" $
-  P_3 (m# +# n#) (appPR pra as1 as2) (appPR prb bs1 bs2) (appPR prc cs1 cs2)
+  P_3 (appPR pra as1 as2)
+      (appPR prb bs1 bs2)
+      (appPR prc cs1 cs2)
 
 {-# INLINE applPR_3 #-}
-applPR_3 pra prb prc is (P_3 m# as1 bs1 cs1) js (P_3 n# as2 bs2 cs2)
+applPR_3 pra prb prc is (P_3 as1 bs1 cs1) js (P_3 as2 bs2 cs2)
   = traceFn "applPR_3" $
-  P_3 (m# +# n#) (applPR pra is as1 js as2)
-                   (applPR prb is bs1 js bs2)
-                   (applPR prc is cs1 js cs2)
+  P_3 (applPR pra is as1 js as2)
+      (applPR prb is bs1 js bs2)
+      (applPR prc is cs1 js cs2)
 
 {-# INLINE packPR_3 #-}
-packPR_3 pra prb prc (P_3 as bs cs) n# sel#
+packPR_3 pra prb prc (P_3 as bs cs) n# sel#
   = traceFn "packPR_3" $
-  P_3 n# (packPR pra as n# sel#)
-           (packPR prb bs n# sel#)
-           (packPR prc cs n# sel#)
+  P_3 (packPR pra as n# sel#)
+      (packPR prb bs n# sel#)
+      (packPR prc cs n# sel#)
 
 {-# INLINE combine2PR_3 #-}
-combine2PR_3 pra prb prc n# sel# is# (P_3 _ as1 bs1 cs1)
-                                     (P_3 _ as2 bs2 cs2)
+combine2PR_3 pra prb prc n# sel (P_3 as1 bs1 cs1)
+                                (P_3 as2 bs2 cs2)
   = traceFn "combine2PR_3" $
-  P_3 n# (combine2PR pra n# sel# is# as1 as2)
-           (combine2PR prb n# sel# is# bs1 bs2)
-           (combine2PR prc n# sel# is# cs1 cs2)
+  P_3 (combine2PR pra n# sel as1 as2)
+      (combine2PR prb n# sel bs1 bs2)
+      (combine2PR prc n# sel cs1 cs2)
 
 {-# INLINE fromListPR_3 #-}
 fromListPR_3 pra prb prc n# xs
-  = P_3 n# (fromListPR pra n# as)
-           (fromListPR prb n# bs)
-           (fromListPR prc n# cs)
+  = P_3 (fromListPR pra n# as)
+        (fromListPR prb n# bs)
+        (fromListPR prc n# cs)
   where
     (as,bs,cs) = unzip3 xs
 
 {-# INLINE nfPR_3 #-}
-nfPR_3 pra prb prc (P_3 as bs cs)
+nfPR_3 pra prb prc (P_3 as bs cs)
   = nfPR pra as
     `seq` nfPR prb bs
     `seq` nfPR prc cs
 
-zip3PA# :: PA a -> PA b -> PA c
-        -> PArray a -> PArray b -> PArray c -> PArray (a,b,c)
+zip3PA# :: PArray a -> PArray b -> PArray c -> PArray (a,b,c)
 {-# INLINE_PA zip3PA# #-}
-zip3PA# pa pb pc xs ys zs = traceFn "zip3PA" $
-        P_3 (lengthPA# pa xs) xs ys zs
+zip3PA# (PArray n# xs) (PArray _ ys) (PArray _ zs) = PArray n# (P_3 xs ys zs)
 
 dPR_4 :: PR a -> PR b -> PR c -> PR d -> PR (a,b,c,d)
 {-# INLINE dPR_4 #-}
 dPR_4 pra prb prc prd
   = PR {
-      lengthPR     = lengthPR_4
-    , emptyPR      = emptyPR_4 pra prb prc prd
+      emptyPR      = emptyPR_4 pra prb prc prd
     , replicatePR  = replicatePR_4 pra prb prc prd
     , replicatelPR = replicatelPR_4 pra prb prc prd
     , repeatPR     = repeatPR_4 pra prb prc prd
@@ -596,116 +545,113 @@ dPR_4 pra prb prc prd
     , nfPR         = nfPR_4 pra prb prc prd
     }
 
-{-# INLINE lengthPR_4 #-}
-lengthPR_4 (P_4 n# _ _ _ _) = n#
-
 {-# INLINE emptyPR_4 #-}
 emptyPR_4 pra prb prc prd = traceFn "emptyPR_4" $
-          P_4 0# (emptyPR pra)
-                                   (emptyPR prb)
-                                   (emptyPR prc)
-                                   (emptyPR prd)
+          P_4 (emptyPR pra)
+              (emptyPR prb)
+              (emptyPR prc)
+              (emptyPR prd)
 
 {-# INLINE replicatePR_4 #-}
-replicatePR_4 pra prb prc prd n# ~(a,b,c,d)
+replicatePR_4 pra prb prc prd n# (a,b,c,d)
   = traceFn "replicatePR_4" $
-  P_4 n# (replicatePR pra n# a)
-           (replicatePR prb n# b)
-           (replicatePR prc n# c)
-           (replicatePR prd n# d)
+  P_4 (replicatePR pra n# a)
+      (replicatePR prb n# b)
+      (replicatePR prc n# c)
+      (replicatePR prd n# d)
 
 {-# INLINE replicatelPR_4 #-}
-replicatelPR_4 pra prb prc prd segd (P_4 as bs cs ds)
+replicatelPR_4 pra prb prc prd segd (P_4 as bs cs ds)
   = traceFn "replicatelPR_4" $
-  P_4 (elementsSegdPA# segd) (replicatelPR pra segd as)
-                             (replicatelPR prb segd bs)
-                             (replicatelPR prc segd cs)
-                             (replicatelPR prd segd ds)
+  P_4 (replicatelPR pra segd as)
+      (replicatelPR prb segd bs)
+      (replicatelPR prc segd cs)
+      (replicatelPR prd segd ds)
 
 {-# INLINE repeatPR_4 #-}
-repeatPR_4 pra prb prc prd n# len# (P_4 as bs cs ds)
+repeatPR_4 pra prb prc prd n# len# (P_4 as bs cs ds)
   = traceFn "repeatPR_4" $
-  P_4 (n# *# len#) (repeatPR pra n# len# as)
-                   (repeatPR prb n# len# bs)
-                   (repeatPR prc n# len# cs)
-                   (repeatPR prd n# len# ds)
+  P_4 (repeatPR pra n# len# as)
+      (repeatPR prb n# len# bs)
+      (repeatPR prc n# len# cs)
+      (repeatPR prd n# len# ds)
 
 {-# INLINE repeatcPR_4 #-}
-repeatcPR_4 pra prb prc prd n# ns segd (P_4 as bs cs ds)
+repeatcPR_4 pra prb prc prd n# ns segd (P_4 as bs cs ds)
   = traceFn "repeatcPR_4" $
-  P_4 n# (repeatcPR pra n# ns segd as)
-         (repeatcPR prb n# ns segd bs)
-         (repeatcPR prc n# ns segd cs)
-         (repeatcPR prd n# ns segd ds)
+  P_4 (repeatcPR pra n# ns segd as)
+      (repeatcPR prb n# ns segd bs)
+      (repeatcPR prc n# ns segd cs)
+      (repeatcPR prd n# ns segd ds)
 
 {-# INLINE indexPR_4 #-}
-indexPR_4 pra prb prc prd (P_4 n# as bs cs ds) i#
+indexPR_4 pra prb prc prd (P_4 as bs cs ds) i#
   = traceFn "indexPR_4" $
   (indexPR pra as i#,
-     indexPR prb bs i#,
-     indexPR prc cs i#,
-     indexPR prd ds i#)
+   indexPR prb bs i#,
+   indexPR prc cs i#,
+   indexPR prd ds i#)
 
 {-# INLINE extractPR_4 #-}
-extractPR_4 pra prb prc prd (P_4 as bs cs ds) i# n#
+extractPR_4 pra prb prc prd (P_4 as bs cs ds) i# n#
   = traceFn "extractPR_4" $
-    P_4 n# (extractPR pra as i# n#)
-           (extractPR prb bs i# n#)
-           (extractPR prc cs i# n#)
-           (extractPR prd ds i# n#)
+    P_4 (extractPR pra as i# n#)
+        (extractPR prb bs i# n#)
+        (extractPR prc cs i# n#)
+        (extractPR prd ds i# n#)
 
 {-# INLINE bpermutePR_4 #-}
-bpermutePR_4 pra prb prc prd n# (P_4 _ as bs cs ds) is
+bpermutePR_4 pra prb prc prd (P_4 as bs cs ds) n# is
   = traceFn "bpermutePR_4" $
-  P_4 n# (bpermutePR pra n# as is)
-         (bpermutePR prb n# bs is)
-         (bpermutePR prc n# cs is)
-         (bpermutePR prd n# ds is)
+  P_4 (bpermutePR pra as n# is)
+      (bpermutePR prb bs n# is)
+      (bpermutePR prc cs n# is)
+      (bpermutePR prd ds n# is)
 
 {-# INLINE appPR_4 #-}
-appPR_4 pra prb prc prd (P_4 m# as1 bs1 cs1 ds1) (P_4 n# as2 bs2 cs2 ds2)
+appPR_4 pra prb prc prd (P_4 as1 bs1 cs1 ds1) (P_4 as2 bs2 cs2 ds2)
   = traceFn "appPR_4" $
-  P_4 (m# +# n#) (appPR pra as1 as2)
-                   (appPR prb bs1 bs2)
-                   (appPR prc cs1 cs2)
-                   (appPR prd ds1 ds2)
+  P_4 (appPR pra as1 as2)
+      (appPR prb bs1 bs2)
+      (appPR prc cs1 cs2)
+      (appPR prd ds1 ds2)
 
 {-# INLINE applPR_4 #-}
-applPR_4 pra prb prc prd is (P_4 m# as1 bs1 cs1 ds1) js (P_4 n# as2 bs2 cs2 ds2)
+applPR_4 pra prb prc prd is (P_4 as1 bs1 cs1 ds1) js (P_4 as2 bs2 cs2 ds2)
   = traceFn "applPR_4" $
-  P_4 (m# +# n#) (applPR pra is as1 js as2)
-                   (applPR prb is bs1 js bs2)
-                   (applPR prc is cs1 js cs2)
-                   (applPR prd is ds1 js ds2)
+  P_4 (applPR pra is as1 js as2)
+      (applPR prb is bs1 js bs2)
+      (applPR prc is cs1 js cs2)
+      (applPR prd is ds1 js ds2)
 
 {-# INLINE packPR_4 #-}
-packPR_4 pra prb prc prd (P_4 as bs cs ds) n# sel#
+packPR_4 pra prb prc prd (P_4 as bs cs ds) n# sel#
   = traceFn "packPR_4" $
-  P_4 n# (packPR pra as n# sel#)
-           (packPR prb bs n# sel#)
-           (packPR prc cs n# sel#)
-           (packPR prd ds n# sel#)
+  P_4 (packPR pra as n# sel#)
+      (packPR prb bs n# sel#)
+      (packPR prc cs n# sel#)
+      (packPR prd ds n# sel#)
 
 {-# INLINE combine2PR_4 #-}
-combine2PR_4 pra prb prc prd n# sel# is# (P_4 _ as1 bs1 cs1 ds1)
-                                         (P_4 _ as2 bs2 cs2 ds2)
+combine2PR_4 pra prb prc prd n# sel (P_4 as1 bs1 cs1 ds1)
+                                    (P_4 as2 bs2 cs2 ds2)
   = traceFn "combine2PR_4" $
-  P_4 n# (combine2PR pra n# sel# is# as1 as2)
-           (combine2PR prb n# sel# is# bs1 bs2)
-           (combine2PR prc n# sel# is# cs1 cs2)
-           (combine2PR prd n# sel# is# ds1 ds2)
+  P_4 (combine2PR pra n# sel as1 as2)
+      (combine2PR prb n# sel bs1 bs2)
+      (combine2PR prc n# sel cs1 cs2)
+      (combine2PR prd n# sel ds1 ds2)
 
 {-# INLINE fromListPR_4 #-}
 fromListPR_4 pra prb prc prd n# xs
-  = P_4 n# (fromListPR pra n# as)
-           (fromListPR prb n# bs)
-           (fromListPR prc n# cs)
-           (fromListPR prd n# ds)
+  = P_4 (fromListPR pra n# as)
+        (fromListPR prb n# bs)
+        (fromListPR prc n# cs)
+        (fromListPR prd n# ds)
   where
     (as,bs,cs,ds) = L.unzip4 xs
 
 {-# INLINE nfPR_4 #-}
-nfPR_4 pra prb prc prd (P_4 as bs cs ds)
+nfPR_4 pra prb prc prd (P_4 as bs cs ds)
   = nfPR pra as
     `seq` nfPR prb bs
     `seq` nfPR prc cs
@@ -715,8 +661,7 @@ dPR_5 :: PR a -> PR b -> PR c -> PR d -> PR e -> PR (a,b,c,d,e)
 {-# INLINE dPR_5 #-}
 dPR_5 pra prb prc prd pre
   = PR {
-      lengthPR     = lengthPR_5
-    , emptyPR      = emptyPR_5 pra prb prc prd pre
+      emptyPR      = emptyPR_5 pra prb prc prd pre
     , replicatePR  = replicatePR_5 pra prb prc prd pre
     , replicatelPR = replicatelPR_5 pra prb prc prd pre
     , repeatPR     = repeatPR_5 pra prb prc prd pre
@@ -732,132 +677,129 @@ dPR_5 pra prb prc prd pre
     , nfPR         = nfPR_5 pra prb prc prd pre
     }
 
-{-# INLINE lengthPR_5 #-}
-lengthPR_5 (P_5 n# _ _ _ _ _) = n#
-
 {-# INLINE emptyPR_5 #-}
 emptyPR_5 pra prb prc prd pre
   = traceFn "emptyPR_5" $
-  P_5 0# (emptyPR pra)
-           (emptyPR prb)
-           (emptyPR prc)
-           (emptyPR prd)
-           (emptyPR pre)
+  P_5 (emptyPR pra)
+      (emptyPR prb)
+      (emptyPR prc)
+      (emptyPR prd)
+      (emptyPR pre)
 
 {-# INLINE replicatePR_5 #-}
-replicatePR_5 pra prb prc prd pre n# ~(a,b,c,d,e)
+replicatePR_5 pra prb prc prd pre n# (a,b,c,d,e)
   = traceFn "replicatePR_5" $
-  P_5 n# (replicatePR pra n# a)
-           (replicatePR prb n# b)
-           (replicatePR prc n# c)
-           (replicatePR prd n# d)
-           (replicatePR pre n# e)
+  P_5 (replicatePR pra n# a)
+      (replicatePR prb n# b)
+      (replicatePR prc n# c)
+      (replicatePR prd n# d)
+      (replicatePR pre n# e)
 
 {-# INLINE replicatelPR_5 #-}
-replicatelPR_5 pra prb prc prd pre segd (P_5 as bs cs ds es)
+replicatelPR_5 pra prb prc prd pre segd (P_5 as bs cs ds es)
   = traceFn "replicatelPR_5" $
-  P_5 (elementsSegdPA# segd) (replicatelPR pra segd as)
-                             (replicatelPR prb segd bs)
-                             (replicatelPR prc segd cs)
-                             (replicatelPR prd segd ds)
-                             (replicatelPR pre segd es)
+  P_5 (replicatelPR pra segd as)
+      (replicatelPR prb segd bs)
+      (replicatelPR prc segd cs)
+      (replicatelPR prd segd ds)
+      (replicatelPR pre segd es)
 
 {-# INLINE repeatPR_5 #-}
-repeatPR_5 pra prb prc prd pre n# len# (P_5 as bs cs ds es)
+repeatPR_5 pra prb prc prd pre n# len# (P_5 as bs cs ds es)
   = traceFn "repeatPR_5" $
-  P_5 (n# *# len#) (repeatPR pra n# len# as)
-                   (repeatPR prb n# len# bs)
-                   (repeatPR prc n# len# cs)
-                   (repeatPR prd n# len# ds)
-                   (repeatPR pre n# len# es)
+  P_5 (repeatPR pra n# len# as)
+      (repeatPR prb n# len# bs)
+      (repeatPR prc n# len# cs)
+      (repeatPR prd n# len# ds)
+      (repeatPR pre n# len# es)
 
 {-# INLINE repeatcPR_5 #-}
-repeatcPR_5 pra prb prc prd pre n# ns segd (P_5 as bs cs ds es)
+repeatcPR_5 pra prb prc prd pre n# ns segd (P_5 as bs cs ds es)
   = traceFn "repeatcPR_5" $
-  P_5 n# (repeatcPR pra n# ns segd as)
-         (repeatcPR prb n# ns segd bs)
-         (repeatcPR prc n# ns segd cs)
-         (repeatcPR prd n# ns segd ds)
-         (repeatcPR pre n# ns segd es)
+  P_5 (repeatcPR pra n# ns segd as)
+      (repeatcPR prb n# ns segd bs)
+      (repeatcPR prc n# ns segd cs)
+      (repeatcPR prd n# ns segd ds)
+      (repeatcPR pre n# ns segd es)
 
 {-# INLINE indexPR_5 #-}
-indexPR_5 pra prb prc prd pre (P_5 n# as bs cs ds es) i#
+indexPR_5 pra prb prc prd pre (P_5 as bs cs ds es) i#
   = traceFn "indexPR_5" $
   (indexPR pra as i#,
-     indexPR prb bs i#,
-     indexPR prc cs i#,
-     indexPR prd ds i#,
-     indexPR pre es i#)
+   indexPR prb bs i#,
+   indexPR prc cs i#,
+   indexPR prd ds i#,
+   indexPR pre es i#)
 
 {-# INLINE extractPR_5 #-}
-extractPR_5 pra prb prc prd pre (P_5 as bs cs ds es) i# n#
+extractPR_5 pra prb prc prd pre (P_5 as bs cs ds es) i# n#
   = traceFn "extractPR_5" $
-    P_5 n# (extractPR pra as i# n#)
-           (extractPR prb bs i# n#)
-           (extractPR prc cs i# n#)
-           (extractPR prd ds i# n#)
-           (extractPR pre es i# n#)
+    P_5 (extractPR pra as i# n#)
+        (extractPR prb bs i# n#)
+        (extractPR prc cs i# n#)
+        (extractPR prd ds i# n#)
+        (extractPR pre es i# n#)
 
 {-# INLINE bpermutePR_5 #-}
-bpermutePR_5 pra prb prc prd pre n# (P_5 _ as bs cs ds es) is
+bpermutePR_5 pra prb prc prd pre (P_5 as bs cs ds es) n# is
   = traceFn "bpermutePR_5" $
-  P_5 n# (bpermutePR pra n# as is)
-         (bpermutePR prb n# bs is)
-         (bpermutePR prc n# cs is)
-         (bpermutePR prd n# ds is)
-         (bpermutePR pre n# es is)
+  P_5 (bpermutePR pra as n# is)
+      (bpermutePR prb bs n# is)
+      (bpermutePR prc cs n# is)
+      (bpermutePR prd ds n# is)
+      (bpermutePR pre es n# is)
 
 {-# INLINE appPR_5 #-}
-appPR_5 pra prb prc prd pre (P_5 m# as1 bs1 cs1 ds1 es1)
-                            (P_5 n# as2 bs2 cs2 ds2 es2)
+appPR_5 pra prb prc prd pre (P_5 as1 bs1 cs1 ds1 es1)
+                            (P_5 as2 bs2 cs2 ds2 es2)
   = traceFn "appPR_5" $
-  P_5 (m# +# n#) (appPR pra as1 as2)
-                   (appPR prb bs1 bs2)
-                   (appPR prc cs1 cs2)
-                   (appPR prd ds1 ds2)
-                   (appPR pre es1 es2)
+  P_5 (appPR pra as1 as2)
+      (appPR prb bs1 bs2)
+      (appPR prc cs1 cs2)
+      (appPR prd ds1 ds2)
+      (appPR pre es1 es2)
 
 {-# INLINE applPR_5 #-}
-applPR_5 pra prb prc prd pre is (P_5 m# as1 bs1 cs1 ds1 es1)
-                             js (P_5 n# as2 bs2 cs2 ds2 es2)
+applPR_5 pra prb prc prd pre is (P_5 as1 bs1 cs1 ds1 es1)
+                             js (P_5 as2 bs2 cs2 ds2 es2)
   = traceFn "applPR_5" $
-  P_5 (m# +# n#) (applPR pra is as1 js as2)
-                   (applPR prb is bs1 js bs2)
-                   (applPR prc is cs1 js cs2)
-                   (applPR prd is ds1 js ds2)
-                   (applPR pre is es1 js es2)
+  P_5 (applPR pra is as1 js as2)
+      (applPR prb is bs1 js bs2)
+      (applPR prc is cs1 js cs2)
+      (applPR prd is ds1 js ds2)
+      (applPR pre is es1 js es2)
 
 {-# INLINE packPR_5 #-}
-packPR_5 pra prb prc prd pre (P_5 as bs cs ds es) n# sel#
+packPR_5 pra prb prc prd pre (P_5 as bs cs ds es) n# sel#
   = traceFn "packPR_5" $
-  P_5 n# (packPR pra as n# sel#)
-           (packPR prb bs n# sel#)
-           (packPR prc cs n# sel#)
-           (packPR prd ds n# sel#)
-           (packPR pre es n# sel#)
+  P_5 (packPR pra as n# sel#)
+      (packPR prb bs n# sel#)
+      (packPR prc cs n# sel#)
+      (packPR prd ds n# sel#)
+      (packPR pre es n# sel#)
 
 {-# INLINE combine2PR_5 #-}
-combine2PR_5 pra prb prc prd pre n# sel# is# (P_5 _ as1 bs1 cs1 ds1 es1)
-                                             (P_5 _ as2 bs2 cs2 ds2 es2)
+combine2PR_5 pra prb prc prd pre n# sel (P_5 as1 bs1 cs1 ds1 es1)
+                                        (P_5 as2 bs2 cs2 ds2 es2)
   = traceFn "combine2PR_5" $
-  P_5 n# (combine2PR pra n# sel# is# as1 as2)
-           (combine2PR prb n# sel# is# bs1 bs2)
-           (combine2PR prc n# sel# is# cs1 cs2)
-           (combine2PR prd n# sel# is# ds1 ds2)
-           (combine2PR pre n# sel# is# es1 es2)
+  P_5 (combine2PR pra n# sel as1 as2)
+      (combine2PR prb n# sel bs1 bs2)
+      (combine2PR prc n# sel cs1 cs2)
+      (combine2PR prd n# sel ds1 ds2)
+      (combine2PR pre n# sel es1 es2)
 
 {-# INLINE fromListPR_5 #-}
 fromListPR_5 pra prb prc prd pre n# xs
-  = P_5 n# (fromListPR pra n# as)
-           (fromListPR prb n# bs)
-           (fromListPR prc n# cs)
-           (fromListPR prd n# ds)
-           (fromListPR pre n# es)
+  = P_5 (fromListPR pra n# as)
+        (fromListPR prb n# bs)
+        (fromListPR prc n# cs)
+        (fromListPR prd n# ds)
+        (fromListPR pre n# es)
   where
     (as,bs,cs,ds,es) = L.unzip5 xs
 
 {-# INLINE nfPR_5 #-}
-nfPR_5 pra prb prc prd pre (P_5 as bs cs ds es)
+nfPR_5 pra prb prc prd pre (P_5 as bs cs ds es)
   = nfPR pra as
     `seq` nfPR prb bs
     `seq` nfPR prc cs
@@ -867,111 +809,264 @@ nfPR_5 pra prb prc prd pre (P_5 _ as bs cs ds es)
 data Sum2 a b = Alt2_1 a | Alt2_2 b
 data Sum3 a b c = Alt3_1 a | Alt3_2 b | Alt3_3 c
 
-data instance PArray (Sum2 a b)
-  = PSum2 Int# PArray_Int# PArray_Int# (PArray a)
-                                      (PArray b)
-
-data instance PArray (Sum3 a b c)
-  = PSum3 Int# PArray_Int# PArray_Int# (PArray a)
-                                       (PArray b)
-                                       (PArray c)
+data instance PData (Sum2 a b)
+  = PSum2 Sel2 (PData a) (PData b)
 
 dPR_Sum2 :: PR a -> PR b -> PR (Sum2 a b)
 {-# INLINE dPR_Sum2 #-}
 dPR_Sum2 pra prb = PR {
-                     lengthPR     = lengthPR_Sum2
-                   , emptyPR      = emptyPR_Sum2 pra prb
+                     emptyPR      = emptyPR_Sum2 pra prb
                    , replicatePR  = replicatePR_Sum2 pra prb
                    , replicatelPR = replicatelPR_Sum2 pra prb
                    , repeatPR     = repeatPR_Sum2 pra prb
                    , indexPR      = indexPR_Sum2 pra prb
-                   , bpermutePR   = bpermutePR_Sum2 pra prb 
                    , appPR        = appPR_Sum2 pra prb 
-                   , applPR       = applPR_Sum2 pra prb 
                    , packPR       = packPR_Sum2 pra prb 
                    , combine2PR   = combine2PR_Sum2 pra prb 
                    }
  
-{-# INLINE lengthPR_Sum2 #-}
-lengthPR_Sum2 (PSum2 n# _ _ _ _) = n#
-
 {-# INLINE emptyPR_Sum2 #-}
 emptyPR_Sum2 pra prb
   = traceFn "emptyPR_Sum2" $
-  PSum2 0# emptyPA_Int# emptyPA_Int# (emptyPR pra) (emptyPR prb)
+  PSum2 (mkSel2 U.empty U.empty 0 0) (emptyPR pra) (emptyPR prb)
 
 {-# INLINE replicatePR_Sum2 #-}
-replicatePR_Sum2 pra prb n# p
+replicatePR_Sum2 pra prb n# (Alt2_1 x)
+  = traceFn "replicatePR_Sum2" $
+    PSum2 (mkSel2 (U.replicate (I# n#) 0)
+                  (U.enumFromStepLen 0 1 (I# n#))
+                  (I# n#) 0)
+          (replicatePR pra n# x)
+          (emptyPR prb)
+replicatePR_Sum2 pra prb n# (Alt2_2 x)
   = traceFn "replicatePR_Sum2" $
-      PSum2 n# (replicatePA_Int# n# (case p of Alt2_1 _ -> 0#
-                                               Alt2_2 _ -> 1#))
-             (upToPA_Int# n#)
-             (case p of Alt2_1 x -> replicatePR pra n# x
-                        _        -> emptyPR pra)
-             (case p of Alt2_2 y -> replicatePR prb n# y
-                        _        -> emptyPR prb)
+    PSum2 (mkSel2 (U.replicate (I# n#) 1)
+                  (U.enumFromStepLen 0 1 (I# n#))
+                  0 (I# n#))
+          (emptyPR pra)
+          (replicatePR prb n# x)
 
 {-# INLINE replicatelPR_Sum2 #-}
-replicatelPR_Sum2 pra prb segd (PSum2 m# sel# is# as bs)
+replicatelPR_Sum2 pra prb segd (PSum2 sel as bs)
   = traceFn "replicatelPR_Sum2" $
-    PSum2 (elementsSegdPA# segd) sel' is' as' bs'
+    PSum2 sel' as' bs'
   where
-    as'       = replicatelPR pra lsegd as
-    bs'       = replicatelPR prb rsegd bs
-    sel'      = replicatelPA_Int# segd sel#
-    llens     = pack'PA_Int# lens (selectPA_Int# sel# 0#)
-    rlens     = pack'PA_Int# lens (selectPA_Int# sel# 1#)
-    lsegd     = lengthsToSegdPA# llens
-    rsegd     = lengthsToSegdPA# rlens
-    is'       = selectorToIndices2PA# sel'
+    tags      = tagsSel2 sel
+    tags'     = U.replicate_s segd tags
+    sel'      = tagsToSel2 tags'
 
-    lens      = lengthsSegdPA# segd
+    lens      = U.lengthsSegd segd
+
+    asegd     = U.lengthsToSegd
+              . U.pack lens
+              $ U.pick tags 0
+    bsegd     = U.lengthsToSegd
+              . U.pack lens
+              $ U.pick tags 1
+
+    as'       = replicatelPR pra asegd as
+    bs'       = replicatelPR prb bsegd bs
 
 {-# INLINE repeatPR_Sum2 #-}
-repeatPR_Sum2 pra prb n# len# (PSum2 m# sel# is# as bs)
+repeatPR_Sum2 pra prb m# n# (PSum2 sel as bs)
   = traceFn "repeatPR_Sum2" $
-    PSum2 (n# *# len#) sel' is' as' bs'
+    PSum2 sel' as' bs'
   where
-    as'  = repeatPR pra n# (lengthPR pra as) as
-    bs'  = repeatPR prb n# (lengthPR prb bs) bs
-    sel' = repeatPA_Int# n# len# sel#
-    is'  = selectorToIndices2PA# sel'
+    sel' = tagsToSel2
+         . U.repeat (I# m#) (I# n#)
+         $ tagsSel2 sel
+
+    as'  = repeatPR pra m# (elementsSel2_0# sel) as
+    bs'  = repeatPR prb n# (elementsSel2_1# sel) bs
 
 {-# INLINE indexPR_Sum2 #-}
-indexPR_Sum2 pra prb (PSum2 n# sel# is# as bs) i#
+indexPR_Sum2 pra prb (PSum2 sel as bs) i#
   = traceFn "indexPR_Sum2" $
-  case indexPA_Int# sel# i# of
-      0# -> Alt2_1 (indexPR pra as (indexPA_Int# is# i#))
-      _  -> Alt2_2 (indexPR prb bs (indexPA_Int# is# i#))
+  case indicesSel2 sel U.!: I# i# of
+    I# k# -> case tagsSel2 sel U.!: I# i# of
+               0 -> Alt2_1 (indexPR pra as k#)
+               _ -> Alt2_2 (indexPR prb bs k#)
+
+{-# INLINE appPR_Sum2 #-}
+appPR_Sum2 pra prb (PSum2 sel1 as1 bs1)
+                   (PSum2 sel2 as2 bs2)
+  = traceFn "appPR_Sum2" $           
+    PSum2 sel (appPR pra as1 as2)
+              (appPR prb bs1 bs2)
+  where
+    sel = tagsToSel2
+        $ tagsSel2 sel1 U.+:+ tagsSel2 sel2
+
+{-# INLINE packPR_Sum2 #-}
+packPR_Sum2 pra prb (PSum2 sel as bs) m# flags
+  = traceFn "packPR_Sum2" $
+    PSum2 sel' as' bs'
+  where
+    tags   = tagsSel2 sel
+    tags'  = U.pack tags flags
+    sel'   = tagsToSel2 tags'
 
-bpermutePR_Sum2 :: PR a -> PR b -> Int# -> PArray (Sum2 a b) -> PArray_Int# -> PArray (Sum2 a b)
-bpermutePR_Sum2 pra prb _ _ is = traceFn "bpermutePR_Sum2" $
-                error "bpermutePR_Sum2 nyi"
+    aFlags = U.pack flags (U.pick tags 0)
+    bFlags = U.pack flags (U.pick tags 1)
 
-appPR_Sum2 pra prb (PSum2 n1# sel1# _ as1 bs1) (PSum2 n2# sel2# _ as2 bs2) = traceFn "appPR_Sum2" $           
-  PSum2 (n1# +# n2#) (appPA_Int# sel1# sel2#) (error "ind in appPR_Sum2 nyi") (appPR pra as1 as2) (appPR prb bs1 bs2)
+    as'    = packPR pra as (elementsSel2_0# sel') aFlags
+    bs'    = packPR prb bs (elementsSel2_1# sel') bFlags
+
+    _dummy :: Int#
+    _dummy = m#
+
+combine2PR_Sum2 :: PR a -> PR b -> T_combine2PR (Sum2 a b)
+{-# INLINE combine2PR_Sum2 #-}
+combine2PR_Sum2 pra prb n# sel (PSum2 sel1 as1 bs1)
+                               (PSum2 sel2 as2 bs2)
+  = traceFn "combine2PR_Sum2" $
+    PSum2 sel' as bs
+  where
+    tags  = tagsSel2 sel
+    tags' = U.combine (U.pick tags 0) (tagsSel2 sel1) (tagsSel2 sel2)
+    sel'  = tagsToSel2 tags'
 
+    asel = tagsToSel2 (U.pack tags (U.pick tags' 0))
+    bsel = tagsToSel2 (U.pack tags (U.pick tags' 1))
 
-applPR_Sum2 pra prb _ _  = error "applPR_Sum2 nyi"
+    as   = combine2PR pra (elementsSel2_0# sel') asel as1 as2
+    bs   = combine2PR prb (elementsSel2_1# sel') bsel bs1 bs2
+
+{-
+data instance PData (Sum2 a b)
+  = PSum2 (U.Array Int) (U.Array Int) Int# (PData a)
+                                      Int# (PData b)
+
+data instance PData (Sum3 a b c)
+  = PSum3 (U.Array Int) (U.Array Int) Int# (PData a)
+                                      Int# (PData b)
+                                      Int# (PData c)
+
+dPR_Sum2 :: PR a -> PR b -> PR (Sum2 a b)
+{-# INLINE dPR_Sum2 #-}
+dPR_Sum2 pra prb = PR {
+                     emptyPR      = emptyPR_Sum2 pra prb
+                   , replicatePR  = replicatePR_Sum2 pra prb
+                   , replicatelPR = replicatelPR_Sum2 pra prb
+                   , repeatPR     = repeatPR_Sum2 pra prb
+                   , indexPR      = indexPR_Sum2 pra prb
+                   , appPR        = appPR_Sum2 pra prb 
+                   , packPR       = packPR_Sum2 pra prb 
+                   , combine2PR   = combine2PR_Sum2 pra prb 
+                   }
  
-packPR_Sum2 :: PR a -> PR b -> PArray (Sum2 a b) -> Int# -> PArray_Bool# -> PArray (Sum2 a b)
-packPR_Sum2 pra prb  (PSum2 n# sel# _ as bs) m# flags
+{-# INLINE emptyPR_Sum2 #-}
+emptyPR_Sum2 pra prb
+  = traceFn "emptyPR_Sum2" $
+  PSum2 U.empty U.empty 0# (emptyPR pra)
+                        0# (emptyPR prb)
+
+{-# INLINE replicatePR_Sum2 #-}
+replicatePR_Sum2 pra prb n# (Alt2_1 x)
+  = traceFn "replicatePR_Sum2" $
+    PSum2 (U.replicate (I# n#) 0)
+          (U.enumFromStepLen 0 1 (I# n#))
+          n# (replicatePR pra n# x)
+          0# (emptyPR prb)
+replicatePR_Sum2 pra prb n# (Alt2_2 x)
+  = traceFn "replicatePR_Sum2" $
+    PSum2 (U.replicate (I# n#) 1)
+          (U.enumFromStepLen 0 1 (I# n#))
+          0# (emptyPR pra)
+          n# (replicatePR prb n# x)
+
+{-# INLINE replicatelPR_Sum2 #-}
+replicatelPR_Sum2 pra prb segd (PSum2 sel is _ as _ bs)
+  = traceFn "replicatelPR_Sum2" $
+    PSum2 sel' is' (elementsSegd# asegd) as'
+                   (elementsSegd# bsegd) bs'
+  where
+    sel'      = U.replicate_s segd sel
+    is'       = U.selectorToIndices2 sel'
+
+    lens      = U.lengthsSegd segd
+
+    asegd     = U.lengthsToSegd
+              . U.pack lens
+              $ U.pick sel 0
+    bsegd     = U.lengthsToSegd
+              . U.pack lens
+              $ U.pick sel 1
+
+    as'       = replicatelPR pra asegd as
+    bs'       = replicatelPR prb bsegd bs
+
+{-# INLINE repeatPR_Sum2 #-}
+repeatPR_Sum2 pra prb m# n# (PSum2 sel is an# as bn# bs)
+  = traceFn "repeatPR_Sum2" $
+    PSum2 sel' is' (m# *# an#) as'
+                   (m# *# bn#) bs'
+  where
+    sel' = U.repeat (I# m#) (I# n#) sel
+    is'  = U.selectorToIndices2 sel'
+
+    !an'# = m# *# an#
+    !bn'# = m# *# bn#
+
+    as'  = repeatPR pra m# an# as
+    bs'  = repeatPR prb n# bn# bs
+
+{-# INLINE indexPR_Sum2 #-}
+indexPR_Sum2 pra prb (PSum2 sel is _ as _ bs) i#
+  = traceFn "indexPR_Sum2" $
+  case is U.!: I# i# of
+    I# k# -> case sel U.!: I# i# of
+               0 -> Alt2_1 (indexPR pra as k#)
+               _ -> Alt2_2 (indexPR prb bs k#)
+
+{-# INLINE appPR_Sum2 #-}
+appPR_Sum2 pra prb (PSum2 sel1 _ an1# as1 bn1# bs1)
+                   (PSum2 sel2 _ an2# as2 bn2# bs2)
+  = traceFn "appPR_Sum2" $           
+    PSum2 sel is (an1# +# an2#) (appPR pra as1 as2)
+                 (bn1# +# bn2#) (appPR prb bs1 bs2)
+  where
+    sel = sel1 U.+:+ sel2
+    is  = U.selectorToIndices2 sel
+
+{-# INLINE packPR_Sum2 #-}
+packPR_Sum2 pra prb (PSum2 sel _ an# as bn# bs) m# flags
   = traceFn "packPR_Sum2" $
-    PSum2 m# sel' is as' bs'
+    PSum2 sel' is' an'# as' bn'# bs'
+  where
+    sel'   = U.pack sel flags
+    is'    = U.selectorToIndices2 sel'
+
+    aFlags = U.pack flags (U.pick sel 0)
+    bFlags = U.pack flags (U.pick sel 1)
+
+    !bn'#   = case U.count bFlags True of I# n# -> n#
+    !an'#   = m# -# bn'#
+
+    as'    = packPR pra as an'# aFlags
+    bs'    = packPR prb bs bn'# bFlags
+
+combine2PR_Sum2 :: PR a -> PR b -> T_combine2PR (Sum2 a b)
+{-# INLINE combine2PR_Sum2 #-}
+combine2PR_Sum2 pra prb n# sel is (PSum2 sel1 _ an1# as1 bn1# bs1)
+                                  (PSum2 sel2 _ an2# as2 bn2# bs2)
+  = traceFn "combine2PR_Sum2" $
+    PSum2 sel' is' an# as bn# bs
   where
-    sel'   = packPA_Int# sel# m# flags
+    sel' = U.combine (U.pick sel 0) sel1 sel2
+    is'  = U.selectorToIndices2 sel'
+   
+    !an# = an1# +# an2#
+    !bn# = bn1# +# bn2#
 
-    aFlags = packPA_Bool# flags (lengthPR pra as) (selectPA_Int# sel# 0#)
-    bFlags = packPA_Bool# flags (lengthPR prb bs) (selectPA_Int# sel# 1#)
-    !k#    = truesPA_Bool# bFlags
+    asel = U.pack sel (U.pick sel' 0)
+    bsel = U.pack sel (U.pick sel' 1)
 
-    as'    = packPR pra as (m# -# k#) aFlags
-    bs'    = packPR prb bs k# bFlags
-    is     = error "packPR_Sum2 index not impl"
+    as   = combine2PR pra an# asel (U.selectorToIndices2 asel) as1 as2
+    bs   = combine2PR prb bn# bsel (U.selectorToIndices2 bsel) bs1 bs2
 
-combine2PR_Sum2:: PR a -> PR b -> Int# -> PArray_Int# -> PArray_Int#
-                              -> PArray (Sum2 a b) -> PArray (Sum2 a b) -> PArray (Sum2 a b)
-combine2PR_Sum2 pra prb n# sel# is# (PSum2 m1# sel1# _ as1 bs1) (PSum2 m2# sel2# _ as2 bs2) = traceFn "combine2PR_Sum2" $                
+{-
+= traceFn "combine2PR_Sum2" $                
      case   (sel'Bool, nsel'Bool) of
        (s1#, s2#) ->  traceArgs ("combinePR_Sum\nn  = " ++ show (I# n#)  ++ "\n" ++
                                  "m1 = " ++ show (I# m1#)  ++ "\n" ++
@@ -1000,58 +1095,63 @@ combine2PR_Sum2 pra prb n# sel# is# (PSum2 m1# sel1# _ as1 bs1) (PSum2 m2# sel2#
        sel' = combine2PA_Int# n# sel# is#  sel1# sel2#
        sel'Bool  = selectPA_Int# sel' 0#
        nsel'Bool = selectPA_Int# sel' 1#
-
+-}
 
 dPR_Sum3 :: PR a -> PR b -> PR c -> PR (Sum3 a b c)
 {-# INLINE dPR_Sum3 #-}
 dPR_Sum3 pra prb prc
   = PR {
-     lengthPR    = lengthPR_Sum3
-   , emptyPR     = emptyPR_Sum3 pra prb prc
+     emptyPR     = emptyPR_Sum3 pra prb prc
    , replicatePR = replicatePR_Sum3 pra prb prc
    , indexPR     = indexPR_Sum3 pra prb prc
    }
 
-{-# INLINE lengthPR_Sum3 #-}
-lengthPR_Sum3 (PSum3 n# _ _ _ _ _) = n#
-
 {-# INLINE emptyPR_Sum3 #-}
 emptyPR_Sum3 pra prb prc        
   = traceFn "emptyPR_Sum3\n" $
-  PSum3 0# emptyPA_Int# emptyPA_Int# (emptyPR pra)
-                                       (emptyPR prb)
-                                       (emptyPR prc)
+  PSum3 U.empty U.empty 0# (emptyPR pra)
+                        0# (emptyPR prb)
+                        0# (emptyPR prc)
 
 {-# INLINE replicatePR_Sum3 #-}
-replicatePR_Sum3 pra prb prc n# p
+replicatePR_Sum3 pra prb prc n# (Alt3_1 x)
   = traceFn "replicatePR_Sum3\n" $
-  PSum3 n# (replicatePA_Int# n# (case p of Alt3_1 _ -> 0#
-                                           Alt3_2 _ -> 1#
-                                           Alt3_3 _ -> 2#))
-             (upToPA_Int# n#)
-             (case p of Alt3_1 x -> replicatePR pra n# x
-                        _        -> emptyPR pra)
-             (case p of Alt3_2 x -> replicatePR prb n# x
-                        _        -> emptyPR prb)
-             (case p of Alt3_3 x -> replicatePR prc n# x
-                        _        -> emptyPR prc)
+  PSum3 (U.replicate (I# n#) 0)
+        (U.enumFromStepLen 0 1 (I# n#))
+        n# (replicatePR pra n# x)
+        0# (emptyPR prb)
+        0# (emptyPR prc)
+replicatePR_Sum3 pra prb prc n# (Alt3_2 x)
+  = traceFn "replicatePR_Sum3\n" $
+  PSum3 (U.replicate (I# n#) 1)
+        (U.enumFromStepLen 0 1 (I# n#))
+        0# (emptyPR pra)
+        n# (replicatePR prb n# x)
+        0# (emptyPR prc)
+replicatePR_Sum3 pra prb prc n# (Alt3_3 x)
+  = traceFn "replicatePR_Sum3\n" $
+  PSum3 (U.replicate (I# n#) 2)
+        (U.enumFromStepLen 0 1 (I# n#))
+        0# (emptyPR pra)
+        0# (emptyPR prb)
+        n# (replicatePR prc n# x)
 
 {-# INLINE indexPR_Sum3 #-}
-indexPR_Sum3 pra prb prc (PSum3 n# sel# is# as bs cs) i#
+indexPR_Sum3 pra prb prc (PSum3 sel is _ as _ bs _ cs) i#
   = traceFn "indexPR_Sum3\n" $
-  case indexPA_Int# sel# i# of
-      0# -> Alt3_1 (indexPR pra as (indexPA_Int# is# i#))
-      1# -> Alt3_2 (indexPR prb bs (indexPA_Int# is# i#))
-      _  -> Alt3_3 (indexPR prc cs (indexPA_Int# is# i#))
+  case is U.!: I# i# of
+    I# k# -> case sel U.!: I# i# of
+               0 -> Alt3_1 (indexPR pra as k#)
+               1 -> Alt3_2 (indexPR prb bs k#)
+               _ -> Alt3_3 (indexPR prc cs k#)
+-}
 
-data instance PArray (PArray a)
-  = PNested Int# PArray_Int# PArray_Int# (PArray a)
+data instance PData (PArray a) = PNested U.Segd (PData a)
 
 dPR_PArray :: PR a -> PR (PArray a)
 {-# INLINE dPR_PArray #-}
 dPR_PArray pr = PR {
-                  lengthPR     = lengthPR_PArray
-                , emptyPR      = emptyPR_PArray pr
+                  emptyPR      = emptyPR_PArray pr
                 , replicatePR  = replicatePR_PArray pr
                 , replicatelPR = replicatelPR_PArray pr
                 , repeatPR     = repeatPR_PArray pr
@@ -1064,157 +1164,131 @@ dPR_PArray pr = PR {
                 , combine2PR   = combine2PR_PArray pr
                 }
 
-{-# INLINE lengthPR_PArray #-}
-lengthPR_PArray (PNested n# _ _ _) = n#
-
+{-
 {-# INLINE nested_lengthPA #-}
 nested_lengthPA xss = traceFn "nested_lengthPA\n" $
                 I# (lengthPR_PArray xss)
+-}
+
 
 {-# INLINE emptyPR_PArray #-}
 emptyPR_PArray pr = traceFn "emptyPR_PArray\n" $
-               PNested 0# emptyPA_Int# emptyPA_Int# (emptyPR pr)
+        PNested (U.mkSegd U.empty U.empty 0) (emptyPR pr)
 
 {-# INLINE replicatePR_PArray #-}
-replicatePR_PArray pr n# xs
+replicatePR_PArray pr n# (PArray m# xs)
   = traceFn "replicatePR_PArray\n" $
-  PNested n# (replicatePA_Int# n# m#)
-             (enumFromStepLenPA_Int# 0# m# n#)
-             (repeatPR pr n# m# xs)
-  where
-    !m# = lengthPR pr xs
+  PNested (U.mkSegd (U.replicate (I# n#) (I# m#))
+                    (U.enumFromStepLen 0 (I# m#) (I# n#))
+                    (I# n# * I# m#))
+          (repeatPR pr n# m# xs)
 
 {-# INLINE indexPR_PArray #-}
-indexPR_PArray pr  (PNested m# lens idxs xs) i#
-  = extractPR pr xs (indexPA_Int# idxs i#)
-                    (indexPA_Int# lens i#)
+indexPR_PArray pr (PNested segd xs) i#
+  = case U.lengthsSegd segd U.!: I# i# of { I# n# ->
+    case U.indicesSegd segd U.!: I# i# of { I# k# ->
+    PArray n# (extractPR pr xs k# n#) }}
 
 {-# INLINE extractPR_PArray #-}
-extractPR_PArray pr (PNested m# lens idxs xs) i# n#
-  = PNested n# lens' idxs' (extractPR pr xs (indexPA_Int# idxs i#)
-                                            (sumPA_Int# lens'))
+extractPR_PArray pr (PNested segd xs) i# n#
+  = case U.indicesSegd segd U.!: I# i# of
+      I# k# -> PNested segd' (extractPR pr xs k# (elementsSegd# segd'))
   where
-    lens' = extractPA_Int# lens i# n#
-    idxs' = unsafe_scanPA_Int# (+) 0 lens'
+    segd' = U.lengthsToSegd
+          $ U.extract (U.lengthsSegd segd) (I# i#) (I# n#)
 
+bpermutePR_PArray :: PR a -> T_bpermutePR (PArray a)
 {-# INLINE bpermutePR_PArray #-}
--- FIXME: this doesn't look right
-bpermutePR_PArray pr m# (PNested n# xslens xsInds xs) is = traceFn "bpermutePR_PArray\n" $
-                  PNested n# xslens' xsInds' xs'
+bpermutePR_PArray pr (PNested segd xs) n# is
+  = traceFn "bpermutePR_PArray\n" $
+    PNested segd' (bpermutePR pr xs (elementsSegd# segd') flat_is)
   where
-    xslens' = bpermutePA_Int# xslens is
-    xsInds' = unsafe_scanPA_Int# (+) 0 xslens'
-    is1     = bpermutePA_Int# xsInds is  
-    is2     = unsafe_zipWithPA_Int# (\x -> \y -> x + y - 1) xslens' is1
-    ps      = enumFromToEachPA_Int# (lengthPR pr xs) is1 is2
-    xs'     = bpermutePR pr (lengthPA_Int# ps) xs ps
+    segd'   = U.lengthsToSegd
+            $ U.bpermute (U.lengthsSegd segd) is
 
-    _dummy :: Int#
-    !_dummy = m#
+    starts  = U.indicesSegd segd'
+    lens    = U.lengthsSegd segd'
+    ends    = U.zipWith (\x y -> x + y - 1) starts lens
+    flat_is = U.enumFromToEach (U.elementsSegd segd') (U.zip starts ends)
 
 {-# INLINE appPR_PArray #-}
-appPR_PArray pr (PNested n# xslens xsInds xs) (PNested m# yslens ysInds ys) = traceFn "appPR_PArray\n" $             
-   PNested (n# +# m#) (appPA_Int# xslens yslens) (appPA_Int# xsInds ysInds)  (appPR pr xs ys)
+appPR_PArray pr (PNested xsegd xs) (PNested ysegd ys)
+  = traceFn "appPR_PArray\n" $             
+    PNested (U.lengthsToSegd (U.lengthsSegd xsegd U.+:+ U.lengthsSegd ysegd))
+            (appPR pr xs ys)
 
 {-# INLINE applPR_PArray #-}
--- applPR_PArray:: PR a -> USegd -> PArray a -> USegd -> PArray a -> PArray a
-applPR_PArray pr is1  xn@(PNested n# xslens xsInds xs) is2 yn@(PNested m# yslens ysInds ys) = traceFn "applPR_PArray\n" $
-   traceArgs ("applPR_PArray:\n" ++
-     show is1 ++ "\n" ++          
-     show xslens ++ "\n" ++          
-     show is2 ++ "\n" ++          
-     show yslens ++ "\n" ++          
-     show lens) $
-   PNested (n# +# m#) lens ids xys
-   where 
-     lens   = appPA_Int#  xslens yslens 
-     xsSegd = sumPAs_Int# is1 xslens
-     ysSegd = sumPAs_Int# is2 yslens
-     ids    = unsafe_scanPA_Int# (+) 0 lens
-     !xlen# = lengthPR pr xs
-     !ylen# = lengthPR pr ys
-     !len#  = xlen# +# ylen#
-     (PNested _ _ _ xys)   = combine2PR_PArray pr len# isel (error "tmp ind nyi") 
-       (PNested n# xsSegd (error "bla1") xs)  (PNested n# ysSegd (error "bla1") ys)
-     isel   = unsafe_mapPA_Int# (fromBool . even)
-            $ enumFromToPA_Int# 1# (2# *# lengthPA_Int# xslens)
-
+applPR_PArray pr segd1 (PNested xsegd xs) segd2 (PNested ysegd ys)
+  = PNested segd (applPR pr xsegd' xs ysegd' ys)
+  where
+    segd = U.lengthsToSegd
+         $ U.append_s segd1 (U.lengthsSegd xsegd) segd2 (U.lengthsSegd ysegd)
 
+    xsegd' = U.lengthsToSegd
+           $ U.sum_s segd1 (U.lengthsSegd xsegd)
+    ysegd' = U.lengthsToSegd
+           $ U.sum_s segd2 (U.lengthsSegd ysegd)
 
 {-# INLINE repeatPR_PArray #-}
-repeatPR_PArray pr n# len# (PNested _ lens _ xs)
+repeatPR_PArray pr n# len# (PNested segd xs)
   = traceFn "repeatPR_PArray\n" $
-  PNested (n# *# len#) lens'
-                       (unsafe_scanPA_Int# (+) 0 lens')
-                       (repeatPR pr n# (lengthPR pr xs) xs)
+  PNested segd' (repeatPR pr n# (elementsSegd# segd) xs)
   where
-    lens' = repeatPA_Int# n# len# lens
+    segd' = U.lengthsToSegd (U.repeat (I# n#) (I# len#) (U.lengthsSegd segd))
 
 {-# INLINE replicatelPR_PArray #-}
-replicatelPR_PArray pr segd {-n# ns-} (PNested _ lens idxs xs)
+replicatelPR_PArray pr segd (PNested xsegd xs)
   = traceFn "replicatelPR_PArray\n" $
-  PNested (elementsSegdPA# segd) new_lens new_idxs
-  $ repeatcPR pr len rlens (mkSegdPA# lens idxs (lengthPR pr xs)) xs
+  PNested xsegd' xs'
   where
-    new_lens = replicatelPA_Int# segd lens
-    new_idxs = unsafe_scanPA_Int# (+) 0 new_lens
-    !len      = sumPA_Int# (unsafe_zipWithPA_Int# (*) rlens lens)
+    xsegd' = U.lengthsToSegd
+           $ U.replicate_s segd (U.lengthsSegd xsegd)
 
-    rlens    = lengthsSegdPA# segd
-{-
-  PNested n# new_lens new_idxs (bpermutePR pr len xs indices)
-  where
-    new_lens = replicatelPA_Int# n# ns lens
-    new_idxs = unsafe_scanPA_Int# (+) 0 new_lens
-    starts = replicatelPA_Int# n# ns idxs
-    ends   = replicatelPA_Int# n# ns
-           $ unsafe_zipWithPA_Int# (\i l -> i+l-1) idxs lens
-
-    len     = sumPA_Int# (unsafe_zipWithPA_Int# (*) ns lens)
-    indices = enumFromToEachPA_Int# len starts ends
--}
+    xs'    = repeatcPR pr (elementsSegd# xsegd')
+                          (U.lengthsSegd segd)
+                          xsegd xs
 
+packPR_PArray :: PR a -> T_packPR (PArray a)
 {-# INLINE packPR_PArray #-}
-packPR_PArray pr (PNested _ lens _ xs) n# bs
+packPR_PArray pr (PNested segd xs) n# flags
   = traceFn "packPR_PArray\n" $
-  PNested n# lens' idxs'
-     (packPR pr xs (sumPA_Int# lens')
-                   (replicatelPA_Bool# (lengthsToSegdPA# lens) bs))
+  PNested segd' xs'
   where
-    lens' = packPA_Int# lens n# bs
-    idxs' = unsafe_scanPA_Int# (+) 0 lens'
+    segd' = U.lengthsToSegd
+          $ U.pack (U.lengthsSegd segd) flags
+
+    xs'   = packPR pr xs (elementsSegd# segd') (U.replicate_s segd flags)
 
+combine2PR_PArray :: PR a -> T_combine2PR (PArray a)
 {-# INLINE combine2PR_PArray #-}
-combine2PR_PArray pr n# sel is (PNested m1# lens1 idxs1 xs)
-                               (PNested m2# lens2 idxs2 ys)
-  = traceFn ("combine2PR_PArray") $
-    traceArgs ("combine2PR_PArray args" ++ show (I# n#) ++ " "  
-                                        ++ show (I# m1#) ++ "\n "  
-                                        ++ show (I# m2#) ++ "\n "  
-                                        ++ show (lens1) ++ "\n"  
-                                        ++ show (lens2) ++ "\n"  
-                                        ++ show (sel') ++ "\n"  
-                                        ++ show (lens) ++ "\n"  
-                                        ++ show sel ++ "\n") $ 
-      PNested n# lens idxs xys
-  where 
-    xys  = combine2PR pr len# sel' is' xs ys
-    lens = combine2PA_Int# (m1# +# m2#) sel is lens1 lens2
-    idxs = unsafe_scanPA_Int# (+) 0 lens
-
-    !xlen# = lengthPR pr xs
-    !ylen# = lengthPR pr ys
-    !len#  = xlen# +# ylen#
-
-    sel' = replicatelPA_Int# (lengthsToSegdPA# lens) sel
-    is'  = selectorToIndices2PA# sel'
-
-segdOfPA# :: PA a -> PArray (PArray a) -> Segd
-{-# INLINE_PA segdOfPA# #-}
-segdOfPA# pa (PNested _ lens idxs xs) = mkSegdPA# lens idxs (lengthPA# pa xs)
+combine2PR_PArray pr n# sel (PNested xsegd xs) (PNested ysegd ys)
+  = traceFn "combine2PR_PArray\n" $
+  PNested segd xys
+  where
+    tags = tagsSel2 sel
+
+    segd = U.lengthsToSegd
+         $ U.combine (U.pick tags 0) (U.lengthsSegd xsegd) (U.lengthsSegd ysegd)
+
+    sel' = tagsToSel2
+         $ U.replicate_s segd tags
+
+    xys  = combine2PR pr (elementsSegd# segd) sel' xs ys
+
+segdPA# :: PArray (PArray a) -> U.Segd
+{-# INLINE_PA segdPA# #-}
+segdPA# (PArray _ (PNested segd _)) = segd
 
 concatPA# :: PArray (PArray a) -> PArray a
 {-# INLINE_PA concatPA# #-}
-concatPA# (PNested _ _ _ xs) = traceFn "concatPA\n" $
-          xs
+concatPA# (PArray _ (PNested segd xs)) = PArray (elementsSegd# segd) xs
+
+segmentPA# :: Int# -> U.Segd -> PArray a -> PArray (PArray a)
+{-# INLINE_PA segmentPA# #-}
+segmentPA# n# segd (PArray _ xs) = PArray n# (PNested segd xs)
+
+copySegdPA# :: PArray (PArray a) -> PArray b -> PArray (PArray b)
+{-# INLINE copySegdPA# #-}
+copySegdPA# (PArray n# (PNested segd _)) (PArray _ xs)
+  = PArray n# (PNested segd xs)
 
index 7a8da67..5181d84 100644 (file)
@@ -9,22 +9,32 @@ import Data.Array.Parallel.Lifted.PArray
 import Data.Array.Parallel.Lifted.Unboxed
 import Data.Array.Parallel.Lifted.Repr
 import Data.Array.Parallel.Lifted.Instances
+import Data.Array.Parallel.Lifted.Selector
 
 import qualified Data.Array.Parallel.Unlifted as U
 
-import Data.Array.Parallel.Base ((:*:)(..), fstS, pairS, unpairS)
+import Data.Array.Parallel.Base ((:*:)(..), fstS, pairS, unpairS,
+                                 fromBool, toBool)
 
 import GHC.Exts ( Int(..), (-#) )
 import GHC.Word ( Word8 )
 
 class U.Elt a => Scalar a where
-  fromUArrPA :: Int -> U.Array a -> PArray a
-  toUArrPA   :: PArray a -> U.Array a
+  fromUArrPD :: U.Array a -> PData a
+  toUArrPD   :: PData a -> U.Array a
   primPA     :: PA a
 
+fromUArrPA :: Scalar a => Int -> U.Array a -> PArray a
+{-# INLINE fromUArrPA #-}
+fromUArrPA (I# n#) xs = PArray n# (fromUArrPD xs)
+
+toUArrPA :: Scalar a => PArray a -> U.Array a
+{-# INLINE toUArrPA #-}
+toUArrPA (PArray _ xs) = toUArrPD xs
+
 prim_lengthPA :: Scalar a => PArray a -> Int
 {-# INLINE prim_lengthPA #-}
-prim_lengthPA xs = I# (lengthPA# primPA xs)
+prim_lengthPA xs = I# (lengthPA# xs)
 
 fromUArrPA' :: Scalar a => U.Array a -> PArray a
 {-# INLINE fromUArrPA' #-}
@@ -61,14 +71,14 @@ scalar_fold1 f = U.fold1 f . toUArrPA
 scalar_folds :: Scalar a => (a -> a -> a) -> a -> PArray (PArray a) -> PArray a
 {-# INLINE_PA scalar_folds #-}
 scalar_folds f z xss = fromUArrPA (prim_lengthPA (concatPA# xss))
-                     . U.fold_s f z (segdOfPA# primPA xss)
+                     . U.fold_s f z (segdPA# xss)
                      . toUArrPA
                      $ concatPA# xss
 
 scalar_fold1s :: Scalar a => (a -> a -> a) -> PArray (PArray a) -> PArray a
 {-# INLINE_PA scalar_fold1s #-}
 scalar_fold1s f xss = fromUArrPA (prim_lengthPA (concatPA# xss))
-                    . U.fold1_s f (segdOfPA# primPA xss)
+                    . U.fold1_s f (segdPA# xss)
                     . toUArrPA
                     $ concatPA# xss
 
@@ -94,68 +104,53 @@ scalar_fold1sIndex f xss = fromUArrPA n
     {-# INLINE f' #-}
     f' p q = pairS $ f (unpairS p) (unpairS q)
 
-    m = I# (lengthPA# (dPA_PArray primPA) xss)
-    n = I# (lengthPA# primPA (concatPA# xss))
+    m = I# (lengthPA# xss)
+    n = I# (lengthPA# (concatPA# xss))
 
-    segd = segdOfPA# primPA xss
+    segd = segdPA# xss
 
 instance Scalar Int where
-  fromUArrPA (I# n#) xs  = PInt n# xs
-  toUArrPA   (PInt _ xs) = xs
+  fromUArrPD xs        = PInt xs
+  toUArrPD   (PInt xs) = xs
   primPA = dPA_Int
 
 instance Scalar Word8 where
-  fromUArrPA (I# n#) xs     = PWord8 n# xs
-  toUArrPA   (PWord8 _ xs) = xs
+  fromUArrPD  xs         = PWord8 xs
+  toUArrPD   (PWord8 xs) = xs
   primPA = dPA_Word8
 
 instance Scalar Double where
-  fromUArrPA (I# n#) xs     = PDouble n# xs
-  toUArrPA   (PDouble _ xs) = xs
+  fromUArrPD  xs          = PDouble xs
+  toUArrPD   (PDouble xs) = xs
   primPA = dPA_Double
 
 instance Scalar Bool where
-  {-# INLINE fromUArrPA #-}
-  fromUArrPA (I# n#) bs
-    = PBool n# ts is
-            (PVoid (n# -# m#))
-            (PVoid m#)
-    where
-      ts = U.map (\b -> if b then 1 else 0) bs
-
-      is = U.zipWith3 if_ ts (U.scan (+) 0 ts) (U.scan (+) 0 $ U.map not_ ts)
-
-      !m# = case U.sum ts of I# m# -> m#
+  {-# INLINE fromUArrPD #-}
+  fromUArrPD bs
+    = PBool (tagsToSel2 (U.map fromBool bs))
 
-      {-# INLINE if_ #-}
-      if_ 0 x y = y
-      if_ _ x y = x
-
-      {-# INLINE not_ #-}
-      not_ 0 = 1
-      not_ _ = 0
-
-  {-# INLINE toUArrPA #-}
-  toUArrPA (PBool _ ts _ _ _) = U.map (/= 0) ts
+  {-# INLINE toUArrPD #-}
+  toUArrPD (PBool sel) = U.map toBool (tagsSel2 sel)
 
   primPA = dPA_Bool
 
 
 fromUArrPA_2 :: (Scalar a, Scalar b) => Int -> U.Array (a :*: b) -> PArray (a,b)
 {-# INLINE fromUArrPA_2 #-}
-fromUArrPA_2 (I# n#) ps = P_2 n# (fromUArrPA (I# n#) xs) (fromUArrPA (I# n#) ys)
+fromUArrPA_2 (I# n#) ps = PArray n# (P_2 (fromUArrPD xs) (fromUArrPD  ys))
   where
     xs :*: ys = U.unzip ps
 
-
-
 fromUArrPA_2' :: (Scalar a, Scalar b) => U.Array (a :*: b) -> PArray (a, b)
 {-# INLINE fromUArrPA_2' #-}
 fromUArrPA_2' ps = fromUArrPA_2 (U.length ps) ps
 
-fromUArrPA_3 :: (Scalar a, Scalar b, Scalar c) => Int -> U.Array (a :*: b :*: c) -> PArray (a,b,c)
+fromUArrPA_3 :: (Scalar a, Scalar b, Scalar c)
+             => Int -> U.Array (a :*: b :*: c) -> PArray (a,b,c)
 {-# INLINE fromUArrPA_3 #-}
-fromUArrPA_3 (I# n#) ps = P_3 n# (fromUArrPA (I# n#) xs) (fromUArrPA (I# n#) ys) (fromUArrPA (I# n#) zs)
+fromUArrPA_3 (I# n#) ps = PArray n# (P_3 (fromUArrPD xs)
+                                         (fromUArrPD ys)
+                                         (fromUArrPD zs))
   where
     xs :*: ys :*: zs = U.unzip3 ps
 
@@ -165,45 +160,9 @@ fromUArrPA_3' ps = fromUArrPA_3 (U.length ps) ps
 
 nestUSegdPA :: Int -> U.Segd -> PArray a -> PArray (PArray a)
 {-# INLINE nestUSegdPA #-}
-nestUSegdPA (I# n#) segd xs = PNested n# (U.lengthsSegd segd)
-                                         (U.indicesSegd segd)
-                                         xs
+nestUSegdPA (I# n#) segd (PArray _ xs) = PArray n# (PNested segd xs)
 
 nestUSegdPA' :: U.Segd -> PArray a -> PArray (PArray a)
 {-# INLINE nestUSegdPA' #-}
 nestUSegdPA' segd xs = nestUSegdPA (U.lengthSegd segd) segd xs
-    
-
-{-
-fromSUArrPA :: Scalar a => Int -> Int -> U.SArray a -> PArray (PArray a)
-{-# INLINE fromSUArrPA #-}
-fromSUArrPA (I# m#) n xss
-  = PNested m# (U.lengths_s xss)
-               (U.indices_s xss)
-               (fromUArrPA n (U.concat xss))
-
-toSUArrPA :: Scalar a => PArray (PArray a) -> U.SArray a
-{-# INLINE toSUArrPA #-}
-toSUArrPA (PNested _ lens idxs xs) = U.toSegd (U.zip lens idxs) U.>: toUArrPA xs
-
-fromSUArrPA_2 :: (Scalar a, Scalar b)
-              => Int -> Int -> U.SArray (a :*: b) -> PArray (PArray (a, b))
-{-# INLINE fromSUArrPA_2 #-}
-fromSUArrPA_2 (I# m#) n pss = PNested m# (U.lengths_s pss)
-                                         (U.indices_s pss)
-                                         (fromUArrPA_2 n (U.concat pss))
-
-fromSUArrPA' :: Scalar a => U.SArray a -> PArray (PArray a)
-{-# INLINE fromSUArrPA' #-}
-fromSUArrPA' xss = fromSUArrPA (U.length_s xss)
-                               (U.length (U.concat xss))
-                               xss
-
-fromSUArrPA_2' :: (Scalar a, Scalar b)
-                => U.SArray (a :*: b) -> PArray (PArray (a, b))
-{-# INLINE fromSUArrPA_2' #-}
-fromSUArrPA_2' pss = fromSUArrPA_2 (U.length_s pss)
-                                   (U.length (U.concat pss))
-                                   pss
--}
 
index 90dd57f..b74baf8 100644 (file)
@@ -3,7 +3,7 @@
 #include "fusion-phases.h"
 
 module Data.Array.Parallel.Lifted.Unboxed (
-  Segd,
+  Segd, elementsSegd#, mkSegd#,
 
   PArray_Int#,
   lengthPA_Int#, emptyPA_Int#,
@@ -15,7 +15,8 @@ module Data.Array.Parallel.Lifted.Unboxed (
   upToPA_Int#, enumFromToPA_Int#, enumFromThenToPA_Int#,
   enumFromStepLenPA_Int#, enumFromToEachPA_Int#,
   selectPA_Int#, selectorToIndices2PA#,
-  lengthsSegdPA#, indicesSegdPA#, elementsSegdPA#, lengthsToSegdPA#, mkSegdPA#,
+  -- lengthSegdPA#, lengthsSegdPA#, indicesSegdPA#, elementsSegdPA#,
+  -- lengthsToSegdPA#, mkSegdPA#,
   sumPA_Int#, sumPAs_Int#,
   unsafe_mapPA_Int#, unsafe_zipWithPA_Int#, unsafe_foldPA_Int#,
   unsafe_scanPA_Int#,
@@ -59,6 +60,34 @@ import Debug.Trace
 
 type Segd = U.Segd
 
+{-
+lengthSegd# :: Segd -> Int#
+lengthSegd# segd = case U.lengthSegd segd of { I# n# -> n# }
+{-# INLINE_PA lengthSegd# #-}
+-}
+
+elementsSegd# :: Segd -> Int#
+elementsSegd# segd = case U.elementsSegd segd of { I# n# -> n# }
+{-# INLINE_PA elementsSegd# #-}
+
+{-
+lengthsToSegdPA# :: PArray_Int# -> Segd
+lengthsToSegdPA# = U.lengthsToSegd
+{-# INLINE_PA lengthsToSegdPA# #-}
+-}
+
+mkSegd# :: U.Array Int -> U.Array Int -> Int# -> Segd
+mkSegd# ns is n# = U.mkSegd ns is (I# n#)
+{-# INLINE_PA mkSegd# #-}
+
+{-# RULES
+
+"mkSegd#" forall ns is n#.
+  mkSegd# ns is n# = U.mkSegd ns is (I# n#)
+
+  #-}
+
+
 type PArray_Int# = U.Array Int
 
 lengthPA_Int# :: PArray_Int# -> Int#
@@ -164,32 +193,6 @@ selectPA_Int# :: PArray_Int# -> Int# -> PArray_Bool#
 selectPA_Int# ns i# = U.map (\n -> n == I# i#) ns
 {-# INLINE_PA selectPA_Int# #-}
 
-lengthsSegdPA# :: Segd -> PArray_Int#
-lengthsSegdPA# = U.lengthsSegd
-{-# INLINE_PA lengthsSegdPA# #-}
-
-indicesSegdPA# :: Segd -> PArray_Int#
-indicesSegdPA# = U.indicesSegd
-{-# INLINE_PA indicesSegdPA# #-}
-
-elementsSegdPA# :: Segd -> Int#
-elementsSegdPA# segd = case U.elementsSegd segd of { I# n# -> n# }
-{-# INLINE_PA elementsSegdPA# #-}
-
-lengthsToSegdPA# :: PArray_Int# -> Segd
-lengthsToSegdPA# = U.lengthsToSegd
-{-# INLINE_PA lengthsToSegdPA# #-}
-
-mkSegdPA# :: PArray_Int# -> PArray_Int# -> Int# -> Segd
-mkSegdPA# ns is n# = U.mkSegd ns is (I# n#)
-{-# INLINE_PA mkSegdPA# #-}
-
-{-# RULES
-
-"mkSegdPA#" forall ns is n#.
-  mkSegdPA# ns is n# = U.mkSegd ns is (I# n#)
-
-  #-}
 
 selectorToIndices2PA# :: PArray_Int# -> PArray_Int#
 selectorToIndices2PA# sel
index e94f728..4138c96 100644 (file)
@@ -3,7 +3,8 @@ module Data.Array.Parallel.Prelude (
 
   , module Data.Array.Parallel.Prelude.Bool
 
-  , PArray, Scalar(..), fromUArrPA', fromUArrPA_2', fromUArrPA_3, fromUArrPA_3'
+  , PArray, Scalar(..), toUArrPA 
+                      , fromUArrPA', fromUArrPA_2', fromUArrPA_3, fromUArrPA_3'
                       , nestUSegdPA'
 ) where
 
index c827c2a..b4a8189 100644 (file)
@@ -18,8 +18,7 @@ module Data.Array.Parallel.Prelude.Base.Int (
   mod, modV, 
   sqrt, sqrtV,
 
-  enumFromToPA, enumFromToP,
-  upToP, upToPA
+  enumFromToPA, enumFromToP
 ) where
 
 import Data.Array.Parallel.Prelude.Base.PArr
@@ -163,11 +162,3 @@ enumFromToP :: Int -> Int ->  [:Int:]
 {-# NOINLINE enumFromToP #-}
 enumFromToP n m = [:n..m:]
 
-upToPA :: Int :-> PArray Int
-{-# INLINE upToPA #-}
-upToPA = closure1 upToPA_Int (\_ -> P.error "Int.upToPA lifted")
-
-upToP :: Int -> [:Int:]
-{-# NOINLINE upToP #-}
-upToP n = enumFromToP 0 n
-
index fb4a3f9..1f017d3 100644 (file)
@@ -9,9 +9,9 @@ import Data.Array.Parallel.Lifted.PArray
 
 tup2 :: PA a -> PA b -> a :-> b :-> (a,b)
 {-# INLINE tup2 #-}
-tup2 pa pb = closure2 pa (,) (zipPA# pa pb)
+tup2 pa pb = closure2 pa (,) zipPA#
 
 tup3 :: PA a -> PA b -> PA c -> a :-> b :-> c :-> (a,b,c)
 {-# INLINE tup3 #-}
-tup3 pa pb pc = closure3 pa pb (,,) (zip3PA# pa pb pc)
+tup3 pa pb pc = closure3 pa pb (,,) zip3PA#
 
index 304183a..7a8df17 100644 (file)
@@ -34,6 +34,7 @@ Library
         Data.Array.Parallel.Lifted.Closure
         Data.Array.Parallel.Lifted.Instances
         Data.Array.Parallel.Lifted.Combinators
+        Data.Array.Parallel.Lifted.Selector
         Data.Array.Parallel.Prelude.Base.Int
         Data.Array.Parallel.Prelude.Base.Word8
         Data.Array.Parallel.Prelude.Base.Double
index dcb1e49..4433124 100644 (file)
@@ -22,6 +22,8 @@ module Data.Array.Parallel.Unlifted (
   fold_s, fold1_s, sum_s, indices_s, sum_r,
   lengthSegd, lengthsSegd, indicesSegd, elementsSegd, lengthsToSegd, mkSegd,
 
+  selectorToIndices2, pick, count,
+
   randoms, randomRs, IOElt, hGet, hPut,
 
   toList, fromList,
index 1522153..3852076 100644 (file)
@@ -1,5 +1,6 @@
+import Data.Array.Parallel.Base ( fromBool )
 import qualified GHC.Base
-import Prelude ((.), ($))
+import Prelude ((.), ($), Num(..), Eq(..))
 
 instance Elt Int
 instance Elt Word8
@@ -131,7 +132,11 @@ append_s :: Elt a => Segd         -- ^ segment descriptor of first array
                   -> Array a
 {-# INLINE_BACKEND append_s #-}
 
-repeat_c :: Elt a => Int -> Array Int -> Segd -> Array a -> Array a
+repeat_c :: Elt a => Int          -- ^ length of the result array
+                  -> Array Int    -- ^ number of time a segment is repeated
+                  -> Segd         -- ^ segment descriptor
+                  -> Array a      -- ^ data array
+                  -> Array a
 {-# INLINE_BACKEND repeat_c #-}
 repeat_c k ns segd xs
   = bpermute xs
@@ -196,6 +201,30 @@ mkSegd :: Array Int -> Array Int -> Int -> Segd
 
  #-}
 
+
+selectorToIndices2 :: Array Int -> Array Int
+{-# INLINE_BACKEND selectorToIndices2 #-}
+selectorToIndices2 sel
+  = zipWith pick sel
+  . scan idx (0 :*: 0)
+  $ map start sel
+  where
+    start 0 = 1 :*: 0
+    start _ = 0 :*: 1
+
+    idx (i1 :*: j1) (i2 :*: j2) = (i1+i2 :*: j1+j2)
+
+    pick 0 (i :*: j) = i
+    pick _ (i :*: j) = j
+
+pick :: (Elt a, Eq a) => Array a -> a -> Array Bool
+{-# INLINE pick #-}
+pick xs x = map (x==) xs
+
+count :: (Elt a, Eq a) => Array a -> a -> Int
+{-# INLINE_BACKEND count #-}
+count xs x = sum (map (fromBool . (==) x) xs)
+
 randoms :: (Elt a, System.Random.Random a, System.Random.RandomGen g)
         => Int -> g -> Array a
 {-# INLINE_BACKEND randoms #-}