yarr 1.2.3 → 1.3.1
raw patch · 20 files changed
+955/−724 lines, 20 files
Files
- Data/Yarr.hs +5/−6
- Data/Yarr/Base.hs +45/−168
- Data/Yarr/Convolution/Eval.hs +0/−2
- Data/Yarr/Convolution/Repr.hs +25/−17
- Data/Yarr/Eval.hs +1/−36
- Data/Yarr/Flow.hs +13/−12
- Data/Yarr/Fusion.hs +346/−0
- Data/Yarr/IO/List.hs +2/−2
- Data/Yarr/Repr/Boxed.hs +6/−3
- Data/Yarr/Repr/Delayed.hs +23/−19
- Data/Yarr/Repr/Foreign.hs +5/−2
- Data/Yarr/Repr/Separate.hs +22/−17
- Data/Yarr/Shape.hs +3/−0
- Data/Yarr/Utils/Fork.hs +16/−15
- Data/Yarr/Walk.hs +274/−0
- Data/Yarr/Walk/Internal.hs +135/−0
- Data/Yarr/Work.hs +0/−270
- Data/Yarr/Work/Internal.hs +0/−135
- Data/Yarr/WorkTypes.hs +20/−14
- yarr.cabal +14/−6
Data/Yarr.hs view
@@ -106,11 +106,7 @@ should be as as precise in types as possible. Don't neglect writing signatures for functions. - 4. You shouldn't be very keen on bang patterns.- They are more likey to harm than improve performance.- However, in 95% of cases GHC ignores them.-- 5. Compilation flags:+ 4. Compilation flags: @-Odph -rtsopts -threaded -fno-liberate-case -funbox-strict-fields@ @-fexpose-all-unfoldings -funfolding-keeness-factor1000@ @-fsimpl-tick-factor=500 -fllvm -optlo-O3@.@@ -130,7 +126,10 @@ * @d-@ prefix stands for \"default\". Typically function with @d-@ prefix is carried version of the one without prefix. - * @f-@ prefix means \"fused\". Used for functions from 'Data.Yarr.Base.Fusion' class.+ * @I-@, @i-@ prefixes for \"indexed\". Functions with this prefix accept+ array index before element itself.++ * @f-@ prefix means \"fused\". Used for functions from 'Data.Yarr.Fusion.Fusion' class. * @-M@, as usual, is for monadic versions of functions. However, if there isn't non-monadic version
Data/Yarr/Base.hs view
@@ -16,12 +16,12 @@ USource(..), UVecSource(..), - -- * Fusion- DefaultFusion(..), Fusion(..),- -- * Manifest and Target classes- UTarget(..), Manifest(..), UVecTarget(..)+ UTarget(..), Manifest(..), UVecTarget(..), + -- * Work index+ PreferredWorkIndex(..), WorkIndex(..),+ ) where import Prelude as P@@ -144,170 +144,6 @@ UVecSource r slr l sh v e --- | Generalized, non-injective version of 'DefaultFusion'. Used internally.------ Minimum complete defenition: 'fmapM', 'fzip2M', 'fzip3M' and 'fzipM'.------ The class doesn't have vector counterpart, it's role play top-level functions--- from "Data.Yarr.Repr.Separate" module.-class Fusion r fr l where- fmap :: (USource r l sh a, USource fr l sh b)- => (a -> b) -- ^ .- -> UArray r l sh a -> UArray fr l sh b- fmap f = fmapM (return . f)- - fmapM :: (USource r l sh a, USource fr l sh b)- => (a -> IO b) -> UArray r l sh a -> UArray fr l sh b-- fzip2 :: (USource r l sh a, USource r l sh b, USource fr l sh c)- => (a -> b -> c) -- ^ .- -> UArray r l sh a- -> UArray r l sh b- -> UArray fr l sh c- fzip2 f = fzip2M (\x y -> return (f x y))-- fzip2M :: (USource r l sh a, USource r l sh b, USource fr l sh c)- => (a -> b -> IO c) -- ^ .- -> UArray r l sh a- -> UArray r l sh b- -> UArray fr l sh c-- fzip3 :: (USource r l sh a, USource r l sh b, USource r l sh c,- USource fr l sh d)- => (a -> b -> c -> d) -- ^ .- -> UArray r l sh a- -> UArray r l sh b- -> UArray r l sh c- -> UArray fr l sh d- fzip3 f = fzip3M (\x y z -> return (f x y z))-- fzip3M :: (USource r l sh a, USource r l sh b, USource r l sh c,- USource fr l sh d)- => (a -> b -> c -> IO d) -- ^ .- -> UArray r l sh a- -> UArray r l sh b- -> UArray r l sh c- -> UArray fr l sh d-- fzip :: (USource r l sh a, USource fr l sh b, Arity n, n ~ S n0)- => Fun n a b -- ^ .- -> VecList n (UArray r l sh a) -> UArray fr l sh b- fzip fun arrs = let funM = P.fmap return fun in fzipM funM arrs-- fzipM :: (USource r l sh a, USource fr l sh b, Arity n, n ~ S n0)- => Fun n a (IO b) -- ^ .- -> VecList n (UArray r l sh a) -> UArray fr l sh b-- {-# INLINE fmap #-}- {-# INLINE fzip2 #-}- {-# INLINE fzip3 #-}- {-# INLINE fzip #-}----- | This class abstracts pair of array types, which could be (preferably should be)--- mapped /(fused)/ one to another. Injective version of 'Fusion' class.--- --- Parameters:------ * @r@ - source array representation. It determines result representation.------ * @fr@ (fused repr) - result (fused) array representation. Result array--- isn't indeed presented in memory, finally it should be--- 'Data.Yarr.Eval.compute'd or 'Data.Yarr.Eval.Load'ed to 'Manifest'--- representation.------ * @l@ - load type, common for source and fused arrays------ All functions are already defined, using non-injective versions from 'Fusion' class.------ The class doesn't have vector counterpart, it's role play top-level functions--- from "Data.Yarr.Repr.Separate" module.-class Fusion r fr l => DefaultFusion r fr l | r -> fr where- -- | /O(1)/ Pure element mapping.- --- -- Main basic \"map\" in Yarr.- dmap :: (USource r l sh a, USource fr l sh b)- => (a -> b) -- ^ Element mapper function- -> UArray r l sh a -- ^ Source array- -> UArray fr l sh b -- ^ Result array- dmap = Data.Yarr.Base.fmap- - -- | /O(1)/ Monadic element mapping.- dmapM :: (USource r l sh a, USource fr l sh b)- => (a -> IO b) -- ^ Monadic element mapper function- -> UArray r l sh a -- ^ Source array- -> UArray fr l sh b -- ^ Result array- dmapM = fmapM-- -- | /O(1)/ Zipping 2 arrays of the same type indexes and shapes.- -- - -- Example:- -- - -- @- -- let productArr = dzip2 (*) arr1 arr2- -- @- dzip2 :: (USource r l sh a, USource r l sh b, USource fr l sh c)- => (a -> b -> c) -- ^ Pure element zipper function- -> UArray r l sh a -- ^ 1st source array- -> UArray r l sh b -- ^ 2nd source array- -> UArray fr l sh c -- ^ Fused result array- dzip2 = fzip2-- -- | /O(1)/ Monadic version of 'dzip2' function.- dzip2M :: (USource r l sh a, USource r l sh b, USource fr l sh c)- => (a -> b -> IO c) -- ^ Monadic element zipper function- -> UArray r l sh a -- ^ 1st source array- -> UArray r l sh b -- ^ 2nd source array- -> UArray fr l sh c -- ^ Result array- dzip2M = fzip2M-- -- | /O(1)/ Zipping 3 arrays of the same type indexes and shapes.- dzip3 :: (USource r l sh a, USource r l sh b, USource r l sh c,- USource fr l sh d)- => (a -> b -> c -> d) -- ^ Pure element zipper function- -> UArray r l sh a -- ^ 1st source array- -> UArray r l sh b -- ^ 2nd source array- -> UArray r l sh c -- ^ 3rd source array- -> UArray fr l sh d -- ^ Result array- dzip3 = fzip3-- -- | /O(1)/ Monadic version of 'dzip3' function.- dzip3M :: (USource r l sh a, USource r l sh b, USource r l sh c,- USource fr l sh d)- => (a -> b -> c -> IO d) -- ^ Monadic element zipper function- -> UArray r l sh a -- ^ 1st source array- -> UArray r l sh b -- ^ 2nd source array- -> UArray r l sh c -- ^ 3rd source array- -> UArray fr l sh d -- ^ Fused result array- dzip3M = fzip3M-- -- | /O(1)/ Generalized element zipping with pure function.- -- Zipper function is wrapped in 'Fun' for injectivity.- dzip :: (USource r l sh a, USource fr l sh b, Arity n, n ~ S n0)- => Fun n a b -- ^ Wrapped function positionally- -- accepts elements from source arrays- -- and emits element for fused array- -> VecList n (UArray r l sh a) -- ^ Source arrays- -> UArray fr l sh b -- ^ Result array- dzip = fzip-- -- | /O(1)/ Monadic version of 'dzip' function.- dzipM :: (USource r l sh a, USource fr l sh b, Arity n, n ~ S n0)- => Fun n a (IO b) -- ^ Wrapped monadic zipper- -> VecList n (UArray r l sh a) -- ^ Source arrays- -> UArray fr l sh b -- ^ Result array- dzipM = fzipM-- {-# INLINE dmap #-}- {-# INLINE dmapM #-}- {-# INLINE dzip2 #-}- {-# INLINE dzip2M #-}- {-# INLINE dzip3 #-}- {-# INLINE dzip3M #-}- {-# INLINE dzip #-}- {-# INLINE dzipM #-}-- -- | Class for mutable arrays. -- -- Just like for 'USource', it's function are unsafe@@ -369,3 +205,44 @@ class (VecRegular tr tslr tl sh v e, UTarget tr tl sh (v e), UTarget tslr tl sh e) => UVecTarget tr tslr tl sh v e+++-- | Internal implementation class. Generalizes @linear-@ and simple+-- indexing and writing function in 'USource' and 'UTarget' classes.+class (Shape sh, Shape i) => WorkIndex sh i where+ gindex :: USource r l sh a => UArray r l sh a -> i -> IO a+ gwrite :: UTarget tr tl sh a => UArray tr tl sh a -> i -> a -> IO ()+ gsize :: USource r l sh a => UArray r l sh a -> i++instance Shape sh => WorkIndex sh sh where+ gindex = index+ gwrite = write+ gsize = extent+ {-# INLINE gindex #-}+ {-# INLINE gwrite #-}+ {-# INLINE gsize #-}++#define WI_INT_INST(sh) \+instance WorkIndex sh Int where { \+ gindex = linearIndex; \+ gwrite = linearWrite; \+ gsize = size . extent; \+ {-# INLINE gindex #-}; \+ {-# INLINE gwrite #-}; \+ {-# INLINE gsize #-}; \+}++WI_INT_INST(Dim2)+WI_INT_INST(Dim3)++-- | Type level fixation of preferred work (load, fold, etc.)+-- index type of the array load type.+--+-- Parameters:+--+-- * @l@ - load type index+--+-- * @sh@ - shape of arrays+--+-- * @i@ - preferred work index, @Int@ or @sh@ itself+class WorkIndex sh i => PreferredWorkIndex l sh i | l sh -> i
Data/Yarr/Convolution/Eval.hs view
@@ -13,8 +13,6 @@ import Data.Yarr.Utils.Split -instance Shape sh => PreferredWorkIndex CVL sh sh- instance (BlockShape sh, UTarget tr tl sh a) => Load CV CVL tr tl sh a where type LoadIndex CVL tl sh = sh
Data/Yarr/Convolution/Repr.hs view
@@ -10,6 +10,7 @@ import Data.Yarr.Base import Data.Yarr.Shape+import Data.Yarr.Fusion import Data.Yarr.Repr.Delayed import Data.Yarr.Utils.FixedVector as V@@ -44,6 +45,8 @@ -- @ffill@ function. data CVL +instance Shape sh => PreferredWorkIndex CVL sh sh+ instance Shape sh => Regular CV CVL sh a where data UArray CV CVL sh a =@@ -93,11 +96,15 @@ {-# INLINE index #-} -instance Fusion CV CV CVL where- fmapM f (Convoluted sh tch iforce bget center cget) =- Convoluted sh tch iforce (f <=< bget) center (f <=< cget)+instance Shape sh => IFusion CV CVL CV CVL sh where+ fimapM f (Convoluted sh tch iforce bget center cget) =+ Convoluted+ sh tch iforce+ (\sh -> bget sh >>= f sh)+ center+ (\sh -> cget sh >>= f sh) - fzip2M f arr1 arr2 =+ fizip2M f arr1 arr2 = let sh = intersect (vl_2 (extent arr1) (extent arr2)) ctr = intersectBlocks (vl_2 (center arr1) (center arr2)) tch = touchArray arr1 >> touchArray arr2@@ -107,17 +114,17 @@ bget sh = do v1 <- borderGet arr1 sh v2 <- borderGet arr2 sh- f v1 v2+ f sh v1 v2 {-# INLINE cget #-} cget sh = do v1 <- centerGet arr1 sh v2 <- centerGet arr2 sh- f v1 v2+ f sh v1 v2 in Convoluted sh tch iforce bget ctr cget - fzip3M f arr1 arr2 arr3 =+ fizip3M f arr1 arr2 arr3 = let sh = intersect (vl_3 (extent arr1) (extent arr2) (extent arr3)) ctr = intersectBlocks (vl_3 (center arr1) (center arr2) (center arr3)) tch = touchArray arr1 >> touchArray arr2 >> touchArray arr3@@ -128,18 +135,18 @@ v1 <- borderGet arr1 sh v2 <- borderGet arr2 sh v3 <- borderGet arr3 sh- f v1 v2 v3+ f sh v1 v2 v3 {-# INLINE cget #-} cget sh = do v1 <- centerGet arr1 sh v2 <- centerGet arr2 sh v3 <- centerGet arr3 sh- f v1 v2 v3+ f sh v1 v2 v3 in Convoluted sh tch iforce bget ctr cget - fzipM fun arrs =+ fizipM ifun arrs = let sh = intersect $ V.map extent arrs ctr = intersectBlocks $ V.map center arrs@@ -152,19 +159,20 @@ {-# INLINE bget #-} bget sh = do v <- V.mapM ($ sh) bgets- inspect v fun+ inspect v (ifun sh) cgets = V.map centerGet arrs {-# INLINE cget #-} cget sh = do v <- V.mapM ($ sh) cgets- inspect v fun+ inspect v (ifun sh) in Convoluted sh tch iforce bget ctr cget - {-# INLINE fmapM #-}- {-# INLINE fzip2M #-}- {-# INLINE fzip3M #-}- {-# INLINE fzipM #-}+ {-# INLINE fimapM #-}+ {-# INLINE fizip2M #-}+ {-# INLINE fizip3M #-}+ {-# INLINE fizipM #-} -instance DefaultFusion CV CV CVL+instance Shape sh => DefaultIFusion CV CVL CV CVL sh+instance Shape sh => DefaultFusion CV CV CVL sh
Data/Yarr/Eval.hs view
@@ -17,11 +17,7 @@ L, SH, -- * Utility- entire,-- -- * Work index- WorkIndex(..), PreferredWorkIndex(..),-+ entire ) where import GHC.Conc@@ -52,37 +48,7 @@ {-# INLINE threads #-} threads = return --- | Internal implementation class.-class (Shape sh, Shape i) => WorkIndex sh i where- gindex :: USource r l sh a => UArray r l sh a -> i -> IO a- gwrite :: UTarget tr tl sh a => UArray tr tl sh a -> i -> a -> IO ()- gsize :: USource r l sh a => UArray r l sh a -> i -instance Shape sh => WorkIndex sh sh where- gindex = index- gwrite = write- gsize = extent- {-# INLINE gindex #-}- {-# INLINE gwrite #-}- {-# INLINE gsize #-}--#define WI_INT_INST(sh) \-instance WorkIndex sh Int where { \- gindex = linearIndex; \- gwrite = linearWrite; \- gsize = size . extent; \- {-# INLINE gindex #-}; \- {-# INLINE gwrite #-}; \- {-# INLINE gsize #-}; \-}--WI_INT_INST(Dim2)-WI_INT_INST(Dim3)---- | Internal implementation class.-class WorkIndex sh i => PreferredWorkIndex l sh i | l sh -> i where-- -- | This class abstracts pair of array types, -- which could be loaded one to another. --@@ -463,4 +429,3 @@ SH_LOAD_INST(SH,L) SH_LOAD_INST(L,SH) SH_LOAD_INST(SH,SH)-
Data/Yarr/Flow.hs view
@@ -2,9 +2,9 @@ -- | Dataflow (fusion operations) module Data.Yarr.Flow ( -- * Basic fusion- DefaultFusion(..),+ DefaultFusion(..), DefaultIFusion(..), - -- ** 'D'elayed flow and zipping shortcuts+ -- ** Delayed flow and zipping shortcuts dzipWith, dzipWith3, D, delay, -- * Vector fusion@@ -17,6 +17,7 @@ ) where import Data.Yarr.Base+import Data.Yarr.Fusion import Data.Yarr.Repr.Delayed import Data.Yarr.Repr.Separate import Data.Yarr.Utils.FixedVector as V@@ -50,7 +51,7 @@ -- @let φs = zipElems ('flip' 'atan2') coords@ zipElems :: (Vector v a,- USource r l sh (v a), USource fr l sh b, DefaultFusion r fr l)+ USource r l sh (v a), USource fr l sh b, DefaultFusion r fr l sh) => Fn (Dim v) a b -- ^ Unwrapped @n@-ary zipper function -> UArray r l sh (v a) -- ^ Source array of vectors -> UArray fr l sh b -- ^ Result array@@ -69,7 +70,7 @@ -- @ mapElems :: (VecRegular r slr l sh v a, USource slr l sh a,- USource fslr l sh b, DefaultFusion slr fslr l, Vector v b)+ USource fslr l sh b, DefaultFusion slr fslr l sh, Vector v b) => (a -> b) -- ^ Mapper function for all elements -> UArray r l sh (v a) -- ^ Source array of vectors -> UArray (SE fslr) l sh (v b) -- ^ Fused array of vectors@@ -84,7 +85,7 @@ -- @let domained = mapElemsM ('Data.Yarr.Utils.Primitive.clampM' 0.0 1.0) floatImage@ mapElemsM :: (VecRegular r slr l sh v a, USource slr l sh a,- USource fslr l sh b, DefaultFusion slr fslr l, Vector v b)+ USource fslr l sh b, DefaultFusion slr fslr l sh, Vector v b) => (a -> IO b) -- ^ Monadic mapper for all vector elements -> UArray r l sh (v a) -- ^ Source array of vectors -> UArray (SE fslr) l sh (v b) -- ^ Fused array of vectors@@ -102,9 +103,9 @@ -- Implemented by means of 'delay' function (source arrays are simply -- delayed before zipping). dzipWith- :: (USource r1 l sh a, DefaultFusion r1 D l, USource D l sh a,- USource r2 l sh b, DefaultFusion r2 D l, USource D l sh b,- USource D l sh c, DefaultFusion D D l)+ :: (USource r1 l sh a, DefaultFusion r1 D l sh, USource D l sh a,+ USource r2 l sh b, DefaultFusion r2 D l sh, USource D l sh b,+ USource D l sh c, DefaultFusion D D l sh) => (a -> b -> c) -- ^ Pure zipping function -> UArray r1 l sh a -- ^ 1st source array -> UArray r2 l sh b -- ^ 2nd source array@@ -115,10 +116,10 @@ -- | /O(1)/ Generalized zipping of 3 arrays, which shouldn't be -- of the same representation type. dzipWith3- :: (USource r1 l sh a, DefaultFusion r1 D l, USource D l sh a,- USource r2 l sh b, DefaultFusion r2 D l, USource D l sh b,- USource r3 l sh c, DefaultFusion r3 D l, USource D l sh c,- USource D l sh d, DefaultFusion D D l)+ :: (USource r1 l sh a, DefaultFusion r1 D l sh, USource D l sh a,+ USource r2 l sh b, DefaultFusion r2 D l sh, USource D l sh b,+ USource r3 l sh c, DefaultFusion r3 D l sh, USource D l sh c,+ USource D l sh d, DefaultFusion D D l sh) => (a -> b -> c -> d) -- ^ Pure zipping function -> UArray r1 l sh a -- ^ 1st source array -> UArray r2 l sh b -- ^ 2nd source array
+ Data/Yarr/Fusion.hs view
@@ -0,0 +1,346 @@+-- | Fusion type system. Use re-exported in "Data.Yarr.Flow" functions.+module Data.Yarr.Fusion where++import Prelude as P++import Data.Yarr.Base+import Data.Yarr.Shape as S+import Data.Yarr.Utils.FixedVector as V++-- | Generalized, non-injective version of 'DefaultFusion'. Used internally.+--+-- Minimum complete defenition: 'fmapM', 'fzip2M', 'fzip3M' and 'fzipM'.+--+-- The class doesn't have vector counterpart, it's role play top-level functions+-- from "Data.Yarr.Repr.Separate" module.+class Fusion r fr l sh where+ fmap :: (USource r l sh a, USource fr l sh b)+ => (a -> b) -- ^ .+ -> UArray r l sh a -> UArray fr l sh b+ fmap f = fmapM (return . f)+ + fmapM :: (USource r l sh a, USource fr l sh b)+ => (a -> IO b) -> UArray r l sh a -> UArray fr l sh b++ fzip2 :: (USource r l sh a, USource r l sh b, USource fr l sh c)+ => (a -> b -> c) -- ^ .+ -> UArray r l sh a+ -> UArray r l sh b+ -> UArray fr l sh c+ fzip2 f = fzip2M (\x y -> return (f x y))++ fzip2M :: (USource r l sh a, USource r l sh b, USource fr l sh c)+ => (a -> b -> IO c) -- ^ .+ -> UArray r l sh a+ -> UArray r l sh b+ -> UArray fr l sh c++ fzip3 :: (USource r l sh a, USource r l sh b, USource r l sh c,+ USource fr l sh d)+ => (a -> b -> c -> d) -- ^ .+ -> UArray r l sh a+ -> UArray r l sh b+ -> UArray r l sh c+ -> UArray fr l sh d+ fzip3 f = fzip3M (\x y z -> return (f x y z))++ fzip3M :: (USource r l sh a, USource r l sh b, USource r l sh c,+ USource fr l sh d)+ => (a -> b -> c -> IO d) -- ^ .+ -> UArray r l sh a+ -> UArray r l sh b+ -> UArray r l sh c+ -> UArray fr l sh d++ fzip :: (USource r l sh a, USource fr l sh b, Arity n, n ~ S n0)+ => Fun n a b -- ^ .+ -> VecList n (UArray r l sh a) -> UArray fr l sh b+ fzip fun arrs = let funM = P.fmap return fun in fzipM funM arrs++ fzipM :: (USource r l sh a, USource fr l sh b, Arity n, n ~ S n0)+ => Fun n a (IO b) -- ^ .+ -> VecList n (UArray r l sh a) -> UArray fr l sh b++ {-# INLINE fmap #-}+ {-# INLINE fzip2 #-}+ {-# INLINE fzip3 #-}+ {-# INLINE fzip #-}+++-- | This class abstracts pair of array types, which could be (preferably should be)+-- mapped /(fused)/ one to another. Injective version of 'Fusion' class.+-- +-- Parameters:+--+-- * @r@ - source array representation. It determines result representation.+--+-- * @fr@ (fused repr) - result (fused) array representation. Result array+-- isn't indeed presented in memory, finally it should be+-- 'Data.Yarr.Eval.compute'd or 'Data.Yarr.Eval.Load'ed to 'Data.Yarr.Base.Manifest'+-- representation.+--+-- * @l@ - load type, common for source and fused arrays+--+-- * @sh@ - shape of arrays+--+-- All functions are already defined, using non-injective versions from 'Fusion' class.+--+-- The class doesn't have vector counterpart, it's role play top-level functions+-- from "Data.Yarr.Repr.Separate" module.+class Fusion r fr l sh => DefaultFusion r fr l sh | r -> fr where+ -- | /O(1)/ Pure element mapping.+ --+ -- Main basic \"map\" in Yarr.+ dmap :: (USource r l sh a, USource fr l sh b)+ => (a -> b) -- ^ Element mapper function+ -> UArray r l sh a -- ^ Source array+ -> UArray fr l sh b -- ^ Result array+ dmap = Data.Yarr.Fusion.fmap+ + -- | /O(1)/ Monadic element mapping.+ dmapM :: (USource r l sh a, USource fr l sh b)+ => (a -> IO b) -- ^ Monadic element mapper function+ -> UArray r l sh a -- ^ Source array+ -> UArray fr l sh b -- ^ Result array+ dmapM = fmapM++ -- | /O(1)/ Zipping 2 arrays of the same type indexes and shapes.+ -- + -- Example:+ -- + -- @+ -- let productArr = dzip2 (*) arr1 arr2+ -- @+ dzip2 :: (USource r l sh a, USource r l sh b, USource fr l sh c)+ => (a -> b -> c) -- ^ Pure element zipper function+ -> UArray r l sh a -- ^ 1st source array+ -> UArray r l sh b -- ^ 2nd source array+ -> UArray fr l sh c -- ^ Fused result array+ dzip2 = fzip2++ -- | /O(1)/ Monadic version of 'dzip2' function.+ dzip2M :: (USource r l sh a, USource r l sh b, USource fr l sh c)+ => (a -> b -> IO c) -- ^ Monadic element zipper function+ -> UArray r l sh a -- ^ 1st source array+ -> UArray r l sh b -- ^ 2nd source array+ -> UArray fr l sh c -- ^ Result array+ dzip2M = fzip2M++ -- | /O(1)/ Zipping 3 arrays of the same type indexes and shapes.+ dzip3 :: (USource r l sh a, USource r l sh b, USource r l sh c,+ USource fr l sh d)+ => (a -> b -> c -> d) -- ^ Pure element zipper function+ -> UArray r l sh a -- ^ 1st source array+ -> UArray r l sh b -- ^ 2nd source array+ -> UArray r l sh c -- ^ 3rd source array+ -> UArray fr l sh d -- ^ Result array+ dzip3 = fzip3++ -- | /O(1)/ Monadic version of 'dzip3' function.+ dzip3M :: (USource r l sh a, USource r l sh b, USource r l sh c,+ USource fr l sh d)+ => (a -> b -> c -> IO d) -- ^ Monadic element zipper function+ -> UArray r l sh a -- ^ 1st source array+ -> UArray r l sh b -- ^ 2nd source array+ -> UArray r l sh c -- ^ 3rd source array+ -> UArray fr l sh d -- ^ Fused result array+ dzip3M = fzip3M++ -- | /O(1)/ Generalized element zipping with pure function.+ -- Zipper function is wrapped in 'Fun' for injectivity.+ dzip :: (USource r l sh a, USource fr l sh b, Arity n, n ~ S n0)+ => Fun n a b -- ^ Wrapped function positionally+ -- accepts elements from source arrays+ -- and emits element for fused array+ -> VecList n (UArray r l sh a) -- ^ Source arrays+ -> UArray fr l sh b -- ^ Result array+ dzip = fzip++ -- | /O(1)/ Monadic version of 'dzip' function.+ dzipM :: (USource r l sh a, USource fr l sh b, Arity n, n ~ S n0)+ => Fun n a (IO b) -- ^ Wrapped monadic zipper+ -> VecList n (UArray r l sh a) -- ^ Source arrays+ -> UArray fr l sh b -- ^ Result array+ dzipM = fzipM++ {-# INLINE dmap #-}+ {-# INLINE dmapM #-}+ {-# INLINE dzip2 #-}+ {-# INLINE dzip2M #-}+ {-# INLINE dzip3 #-}+ {-# INLINE dzip3M #-}+ {-# INLINE dzip #-}+ {-# INLINE dzipM #-}++-- | Like 'Fusion', for mappings/zippings with array index. Used to define+-- functions in 'DefaultIFusion'.+-- +-- Minimum complete defenition: 'fimapM', 'fizip2M', 'fizip3M' and 'fizipM'.+--+-- The class doesn't have vector counterpart.+class PreferredWorkIndex fl sh sh => IFusion r l fr fl sh | r l fr -> fl where+ fimap :: (USource r l sh a, USource fr fl sh b)+ => (sh -> a -> b) -- ^ .+ -> UArray r l sh a -> UArray fr fl sh b+ fimap f = fimapM (\i x -> return (f i x))+ + fimapM :: (USource r l sh a, USource fr fl sh b)+ => (sh -> a -> IO b) -> UArray r l sh a -> UArray fr fl sh b++ fizip2 :: (USource r l sh a, USource r l sh b, USource fr fl sh c)+ => (sh -> a -> b -> c) -- ^ .+ -> UArray r l sh a+ -> UArray r l sh b+ -> UArray fr fl sh c+ fizip2 f = fizip2M (\i x y -> return (f i x y))++ fizip2M :: (USource r l sh a, USource r l sh b, USource fr fl sh c)+ => (sh -> a -> b -> IO c) -- ^ .+ -> UArray r l sh a+ -> UArray r l sh b+ -> UArray fr fl sh c++ fizip3 :: (USource r l sh a, USource r l sh b, USource r l sh c,+ USource fr fl sh d)+ => (sh -> a -> b -> c -> d) -- ^ .+ -> UArray r l sh a+ -> UArray r l sh b+ -> UArray r l sh c+ -> UArray fr fl sh d+ fizip3 f = fizip3M (\i x y z -> return (f i x y z))++ fizip3M :: (USource r l sh a, USource r l sh b, USource r l sh c,+ USource fr fl sh d)+ => (sh -> a -> b -> c -> IO d) -- ^ .+ -> UArray r l sh a+ -> UArray r l sh b+ -> UArray r l sh c+ -> UArray fr fl sh d++ fizip :: (USource r l sh a, USource fr fl sh b, Arity n, n ~ S n0)+ => (sh -> Fun n a b) -- ^ .+ -> VecList n (UArray r l sh a) -> UArray fr fl sh b+ fizip fun arrs = fizipM funM arrs+ where funM i = P.fmap return (fun i)++ fizipM :: (USource r l sh a, USource fr fl sh b, Arity n, n ~ S n0)+ => (sh -> Fun n a (IO b)) -- ^ .+ -> VecList n (UArray r l sh a) -> UArray fr fl sh b++ {-# INLINE fimap #-}+ {-# INLINE fizip2 #-}+ {-# INLINE fizip3 #-}+ {-# INLINE fizip #-}++-- | Like 'DefaultFusion', this class abstracts the pair array types,+-- which should be fused one to another+-- on maps and zips which accept index of element+-- (several elements for zips) in array (arrays).+--+-- Parameters:+--+-- * @r@ - source array representation. Determines result representation.+--+-- * @l@ - source load type+--+-- * @fr@ (fused repr) - result (fused) array representation. Result array+-- isn't indeed presented in memory, finally it should be+-- 'Data.Yarr.Eval.compute'd or 'Data.Yarr.Eval.Load'ed to 'Data.Yarr.Base.Manifest'+-- representation.+--+-- * @fl@ - result, \"shaped\" load type+--+-- * @sh@ - shape of arrays+--+-- All functions are already defined,+-- using non-injective versions from 'IFusion' class.+--+-- The class doesn't have vector counterpart.+class IFusion r l fr fl sh => DefaultIFusion r l fr fl sh | r l -> fr where+ -- | /O(1)/ Pure element mapping with array index.+ imap :: (USource r l sh a, USource fr fl sh b)+ => (sh -> a -> b) -- ^ Indexed mapping function+ -> UArray r l sh a -- ^ Source array+ -> UArray fr fl sh b -- ^ Fused result array+ imap = fimap+ + -- | /O(1)/ Monadic element mapping with index.+ imapM :: (USource r l sh a, USource fr fl sh b)+ => (sh -> a -> IO b) -- ^ Indexed monadic mapping function+ -> UArray r l sh a -- ^ Source array+ -> UArray fr fl sh b -- ^ Result fused array+ imapM = fimapM++ -- | /O(1)/ Pure zipping of 2 arrays with index.+ izip2 :: (USource r l sh a, USource r l sh b, USource fr fl sh c)+ => (sh -> a -> b -> c) -- ^ Indexed zipping function+ -> UArray r l sh a -- ^ 1st source array+ -> UArray r l sh b -- ^ 2nd source array+ -> UArray fr fl sh c -- ^ Fused result array+ izip2 = fizip2++ -- | /O(1)/ Monadic zipping of 2 arrays with index.+ izip2M :: (USource r l sh a, USource r l sh b, USource fr fl sh c)+ => (sh -> a -> b -> IO c) -- ^ Indexed monadic zipping function+ -> UArray r l sh a -- ^ 1st source array+ -> UArray r l sh b -- ^ 2nd source array+ -> UArray fr fl sh c -- ^ Fused result array+ izip2M = fizip2M++ -- | /O(1)/ Pure zipping of 3 arrays with index.+ izip3 :: (USource r l sh a, USource r l sh b, USource r l sh c,+ USource fr fl sh d)+ => (sh -> a -> b -> c -> d) -- ^ Indexed zipping function+ -> UArray r l sh a -- ^ 1st source array+ -> UArray r l sh b -- ^ 2nd source array+ -> UArray r l sh c -- ^ 3rd source array+ -> UArray fr fl sh d -- ^ Fused result array+ izip3 = fizip3++ -- | /O(1)/ Monadic zipping of 3 arrays with index.+ izip3M :: (USource r l sh a, USource r l sh b, USource r l sh c,+ USource fr fl sh d)+ => (sh -> a -> b -> c -> IO d) -- ^ Indexed monadic zipping function+ -> UArray r l sh a -- ^ 1st source array+ -> UArray r l sh b -- ^ 2nd source array+ -> UArray r l sh c -- ^ 3rd source array+ -> UArray fr fl sh d -- ^ Fused result array+ izip3M = fizip3M++ -- | /O(1)/ Generalized pure element zipping with index in arrays.+ -- Zipper function is wrapped in 'Fun' for injectivity.+ izip :: (USource r l sh a, USource fr fl sh b, Arity n, n ~ S n0)+ => (sh -> Fun n a b) -- ^ Accepts index in array and returns+ -- wrapped zipper, which positionally+ -- accepts elements from source arrays+ -- and emits element for the result array+ -> VecList n (UArray r l sh a) -- ^ Bunch of source arrays+ -> UArray fr fl sh b -- ^ Result fused array+ izip = fizip++ -- | /O(1)/ Monadic version of 'izip' function.+ izipM :: (USource r l sh a, USource fr fl sh b, Arity n, n ~ S n0)+ => (sh -> Fun n a (IO b)) -- ^ Monadic indexed zipper+ -> VecList n (UArray r l sh a) -- ^ Source arrays+ -> UArray fr fl sh b -- ^ Result fused array+ izipM = fizipM++ {-# INLINE imap #-}+ {-# INLINE imapM #-}+ {-# INLINE izip2 #-}+ {-# INLINE izip2M #-}+ {-# INLINE izip3 #-}+ {-# INLINE izip3M #-}+ {-# INLINE izip #-}+ {-# INLINE izipM #-}+++instance IFusion r l fr l sh => Fusion r fr l sh where+ fmapM f = fimapM (\_ x -> f x)+ fzip2M f = fizip2M (\_ x y -> f x y)+ fzip3M f = fizip3M (\_ x y z -> f x y z)+ fzipM funM = fizipM (\_ -> funM)+ {-# INLINE fmapM #-}+ {-# INLINE fzip2M #-}+ {-# INLINE fzip3M #-}+ {-# INLINE fzipM #-}
Data/Yarr/IO/List.hs view
@@ -6,7 +6,7 @@ import Data.Yarr.Base import Data.Yarr.Shape as S import Data.Yarr.Eval-import Data.Yarr.Work+import Data.Yarr.Walk import Debug.Yarr @@ -18,7 +18,7 @@ :: (USource r l sh a, PreferredWorkIndex l sh i) => UArray r l sh a -> IO [a] {-# INLINE toList #-}-toList = work (reduceR S.foldr (:)) (return [])+toList = walk (reduceR S.foldr (:)) (return []) -- | /O(n)/ Loads manifest array into memory, with elements -- from flatten list.
Data/Yarr/Repr/Boxed.hs view
@@ -13,7 +13,8 @@ import Control.Monad.ST (RealWorld) import Data.Primitive.Array -import Data.Yarr.Base hiding (fmap)+import Data.Yarr.Base+import Data.Yarr.Fusion hiding (fmap) import Data.Yarr.Shape import Data.Yarr.Repr.Delayed import Data.Yarr.Repr.Separate@@ -46,7 +47,8 @@ linearIndex (Boxed _ arr) = indexArrayM arr {-# INLINE linearIndex #-} -instance DefaultFusion B D L+instance DefaultFusion B D L sh+instance Shape sh => DefaultIFusion B L D SH sh instance (Shape sh, Vector v e, NFData e) => UVecSource (SE B) B L sh v e @@ -70,7 +72,8 @@ linearIndex (MutableBoxed _ marr) = readArray marr {-# INLINE linearIndex #-} -instance DefaultFusion MB D L+instance DefaultFusion MB D L sh+instance Shape sh => DefaultIFusion MB L D SH sh instance (Shape sh, Vector v e, NFData e) => UVecSource (SE MB) MB L sh v e
Data/Yarr/Repr/Delayed.hs view
@@ -19,7 +19,8 @@ import Prelude as P import Control.Monad -import Data.Yarr.Base as B+import Data.Yarr.Base+import Data.Yarr.Fusion as F import Data.Yarr.Eval import Data.Yarr.Shape import Data.Yarr.Utils.FixedVector as V@@ -68,7 +69,7 @@ instance (Shape sh, Vector v e) => UVecSource D D L sh v e -instance Fusion r D L where+instance Fusion r D L sh where fmapM f arr = LinearDelayed (extent arr) (touchArray arr) (force arr) (f <=< linearIndex arr)@@ -124,7 +125,7 @@ {-# INLINE fzip3M #-} {-# INLINE fzipM #-} -instance DefaultFusion D D L+instance DefaultFusion D D L sh @@ -163,12 +164,13 @@ instance (Shape sh, Vector v e) => UVecSource D D SH sh v e -instance Fusion r D SH where- fmapM f arr =+instance Shape sh => IFusion r l D SH sh where+ fimapM f arr = ShapeDelayed- (extent arr) (touchArray arr) (force arr) (f <=< index arr)+ (extent arr) (touchArray arr) (force arr)+ (\sh -> index arr sh >>= f sh) - fzip2M f arr1 arr2 =+ fizip2M f arr1 arr2 = let sh = intersect (vl_2 (extent arr1) (extent arr2)) tch = touchArray arr1 >> touchArray arr2 iforce = force arr1 >> force arr2@@ -177,11 +179,11 @@ get sh = do v1 <- index arr1 sh v2 <- index arr2 sh- f v1 v2+ f sh v1 v2 in ShapeDelayed sh tch iforce get - fzip3M f arr1 arr2 arr3 =+ fizip3M f arr1 arr2 arr3 = let sh = intersect (vl_3 (extent arr1) (extent arr2) (extent arr3)) tch = touchArray arr1 >> touchArray arr2 >> touchArray arr3 iforce = force arr1 >> force arr2 >> force arr3@@ -191,11 +193,11 @@ v1 <- index arr1 sh v2 <- index arr2 sh v3 <- index arr3 sh- f v1 v2 v3+ f sh v1 v2 v3 in ShapeDelayed sh tch iforce get - fzipM fun arrs =+ fizipM ifun arrs = let shapes = V.map extent arrs sh = intersect shapes @@ -207,22 +209,24 @@ {-# INLINE get #-} get sh = do v <- V.mapM ($ sh) gets- inspect v fun+ inspect v (ifun sh) in ShapeDelayed sh tch iforce get - {-# INLINE fmapM #-}- {-# INLINE fzip2M #-}- {-# INLINE fzip3M #-}- {-# INLINE fzipM #-}+ {-# INLINE fimapM #-}+ {-# INLINE fizip2M #-}+ {-# INLINE fizip3M #-}+ {-# INLINE fizipM #-} -instance DefaultFusion D D SH+instance Shape sh => DefaultIFusion D L D SH sh+instance Shape sh => DefaultIFusion D SH D SH sh+instance Shape sh => DefaultFusion D D SH sh -- | Load type preserving wrapping arbirtary array into 'D'elayed representation.-delay :: (USource r l sh a, USource D l sh a, Fusion r D l)+delay :: (USource r l sh a, USource D l sh a, Fusion r D l sh) => UArray r l sh a -> UArray D l sh a {-# INLINE delay #-}-delay = B.fmap id+delay = F.fmap id -- | Wrap indexing function into delayed representation. --
Data/Yarr/Repr/Foreign.hs view
@@ -20,6 +20,7 @@ import Foreign.Marshal.MissingAlloc import Data.Yarr.Base as B+import Data.Yarr.Fusion import Data.Yarr.Repr.Delayed import Data.Yarr.Repr.Separate import Data.Yarr.Shape@@ -66,7 +67,8 @@ linearIndex (ForeignArray _ _ ptr) i = peekElemOff ptr i {-# INLINE linearIndex #-} -instance DefaultFusion F D L+instance DefaultFusion F D L sh+instance Shape sh => DefaultIFusion F L D SH sh -- | Foreign Slice representation, /view/ slice representation -- for 'F'oreign arrays.@@ -120,7 +122,8 @@ linearIndex (ForeignSlice _ vsize _ ptr) i = peekByteOff ptr (i * vsize) {-# INLINE linearIndex #-} -instance DefaultFusion FS D L+instance DefaultFusion FS D L sh+instance Shape sh => DefaultIFusion FS L D SH sh instance (Shape sh, Vector v e, Storable e) => VecRegular F FS L sh v e where
Data/Yarr/Repr/Separate.hs view
@@ -27,6 +27,7 @@ import Data.Functor ((<$>)) import Data.Yarr.Base as B+import Data.Yarr.Fusion import Data.Yarr.Shape import Data.Yarr.Repr.Delayed import Data.Yarr.Utils.FixedVector as V@@ -77,14 +78,18 @@ instance (USource r l sh e, Vector v e) => UVecSource (SE r) r l sh v e -instance (DefaultFusion r D l, Fusion (SE r) D l) => DefaultFusion (SE r) D l+instance (DefaultFusion r D l sh, Fusion (SE r) D l sh) =>+ DefaultFusion (SE r) D l sh +instance (DefaultIFusion r l D SH sh, IFusion (SE r) l D SH sh) =>+ DefaultIFusion (SE r) l D SH sh + -- | Group of @f-...-Elems-@ functions is used internally to define -- @d-...-Elems-@ functions. fmapElems :: (VecRegular r slr l sh v a,- USource slr l sh a, USource fslr l sh b, Fusion slr fslr l,+ USource slr l sh a, USource fslr l sh b, Fusion slr fslr l sh, Vector v2 b, Dim v ~ Dim v2) => VecList (Dim v) (a -> b) -- ^ . -> UArray r l sh (v a)@@ -93,7 +98,7 @@ fmapElemsM :: (VecRegular r slr l sh v a,- USource slr l sh a, USource fslr l sh b, Fusion slr fslr l,+ USource slr l sh a, USource fslr l sh b, Fusion slr fslr l sh, Vector v2 b, Dim v ~ Dim v2) => VecList (Dim v) (a -> IO b) -- ^ . -> UArray r l sh (v a)@@ -104,7 +109,7 @@ fzipElems2 :: (VecRegular r slr l sh v a, USource slr l sh a, VecRegular r slr l sh v b, USource slr l sh b,- USource fslr l sh c, Fusion slr fslr l, Vector v c)+ USource fslr l sh c, Fusion slr fslr l sh, Vector v c) => VecList (Dim v) (a -> b -> c) -- ^ . -> UArray r l sh (v a) -> UArray r l sh (v b)@@ -116,7 +121,7 @@ fzipElems2M :: (VecRegular r slr l sh v a, USource slr l sh a, VecRegular r slr l sh v b, USource slr l sh b,- USource fslr l sh c, Fusion slr fslr l, Vector v c)+ USource fslr l sh c, Fusion slr fslr l sh, Vector v c) => VecList (Dim v) (a -> b -> IO c) -- ^ . -> UArray r l sh (v a) -> UArray r l sh (v b)@@ -136,7 +141,7 @@ :: (VecRegular r slr l sh v a, USource slr l sh a, VecRegular r slr l sh v b, USource slr l sh b, VecRegular r slr l sh v c, USource slr l sh c,- USource fslr l sh d, Fusion slr fslr l, Vector v d)+ USource fslr l sh d, Fusion slr fslr l sh, Vector v d) => VecList (Dim v) (a -> b -> c -> d) -- ^ . -> UArray r l sh (v a) -> UArray r l sh (v b)@@ -150,7 +155,7 @@ :: (VecRegular r slr l sh v a, USource slr l sh a, VecRegular r slr l sh v b, USource slr l sh b, VecRegular r slr l sh v c, USource slr l sh c,- USource fslr l sh d, Fusion slr fslr l, Vector v d)+ USource fslr l sh d, Fusion slr fslr l sh, Vector v d) => VecList (Dim v) (a -> b -> c -> IO d) -- ^ . -> UArray r l sh (v a) -> UArray r l sh (v b)@@ -173,7 +178,7 @@ fzipElems :: (Vector v2 b, Arity m, m ~ S m0, VecRegular r slr l sh v a,- USource slr l sh a, USource fslr l sh b, Fusion slr fslr l)+ USource slr l sh a, USource fslr l sh b, Fusion slr fslr l sh) => VecList (Dim v2) (Fun m a b) -- ^ . -> VecList m (UArray r l sh (v a)) -> UArray (SE fslr) l sh (v2 b)@@ -184,7 +189,7 @@ fzipElemsM :: (Vector v2 b, Arity m, m ~ S m0, VecRegular r slr l sh v a,- USource slr l sh a, USource fslr l sh b, Fusion slr fslr l)+ USource slr l sh a, USource fslr l sh b, Fusion slr fslr l sh) => VecList (Dim v2) (Fun m a (IO b)) -- ^ . -> VecList m (UArray r l sh (v a)) -> UArray (SE fslr) l sh (v2 b)@@ -219,7 +224,7 @@ -- Also, used internally to define 'Data.Yarr.Flow.mapElems' function. dmapElems :: (VecRegular r slr l sh v a,- USource slr l sh a, USource fslr l sh b, DefaultFusion slr fslr l,+ USource slr l sh a, USource fslr l sh b, DefaultFusion slr fslr l sh, Vector v2 b, Dim v ~ Dim v2) => VecList (Dim v) (a -> b) -- ^ Vector of mapper functions -> UArray r l sh (v a) -- ^ Source array of vectors@@ -229,7 +234,7 @@ -- | /O(1)/ Monadic vesion of 'dmapElems' function. dmapElemsM :: (VecRegular r slr l sh v a,- USource slr l sh a, USource fslr l sh b, DefaultFusion slr fslr l,+ USource slr l sh a, USource fslr l sh b, DefaultFusion slr fslr l sh, Vector v2 b, Dim v ~ Dim v2) => VecList (Dim v) (a -> IO b) -- ^ Elemen-wise vector of monadic mappers -> UArray r l sh (v a) -- ^ Source array of vectors@@ -240,7 +245,7 @@ dzipElems2 :: (VecRegular r slr l sh v a, USource slr l sh a, VecRegular r slr l sh v b, USource slr l sh b,- USource fslr l sh c, DefaultFusion slr fslr l, Vector v c)+ USource fslr l sh c, DefaultFusion slr fslr l sh, Vector v c) => VecList (Dim v) (a -> b -> c) -- ^ . -> UArray r l sh (v a) -> UArray r l sh (v b)@@ -250,7 +255,7 @@ dzipElems2M :: (VecRegular r slr l sh v a, USource slr l sh a, VecRegular r slr l sh v b, USource slr l sh b,- USource fslr l sh c, DefaultFusion slr fslr l, Vector v c)+ USource fslr l sh c, DefaultFusion slr fslr l sh, Vector v c) => VecList (Dim v) (a -> b -> IO c) -- ^ . -> UArray r l sh (v a) -> UArray r l sh (v b)@@ -261,7 +266,7 @@ :: (VecRegular r slr l sh v a, USource slr l sh a, VecRegular r slr l sh v b, USource slr l sh b, VecRegular r slr l sh v c, USource slr l sh c,- USource fslr l sh d, DefaultFusion slr fslr l, Vector v d)+ USource fslr l sh d, DefaultFusion slr fslr l sh, Vector v d) => VecList (Dim v) (a -> b -> c -> d) -- ^ . -> UArray r l sh (v a) -> UArray r l sh (v b)@@ -273,7 +278,7 @@ :: (VecRegular r slr l sh v a, USource slr l sh a, VecRegular r slr l sh v b, USource slr l sh b, VecRegular r slr l sh v c, USource slr l sh c,- USource fslr l sh d, DefaultFusion slr fslr l, Vector v d)+ USource fslr l sh d, DefaultFusion slr fslr l sh, Vector v d) => VecList (Dim v) (a -> b -> c -> IO d) -- ^ . -> UArray r l sh (v a) -> UArray r l sh (v b)@@ -287,7 +292,7 @@ dzipElems :: (Vector v2 b, Arity m, m ~ S m0, VecRegular r slr l sh v a,- USource slr l sh a, USource fslr l sh b, DefaultFusion slr fslr l)+ USource slr l sh a, USource fslr l sh b, DefaultFusion slr fslr l sh) => VecList (Dim v2) (Fun m a b) -- ^ Vector of wrapped @m-@ary element-wise zippers -> VecList m (UArray r l sh (v a)) -- ^ Vector of source arrays of vectors -> UArray (SE fslr) l sh (v2 b) -- ^ Fused result array@@ -297,7 +302,7 @@ dzipElemsM :: (Vector v2 b, Arity m, m ~ S m0, VecRegular r slr l sh v a,- USource slr l sh a, USource fslr l sh b, DefaultFusion slr fslr l)+ USource slr l sh a, USource fslr l sh b, DefaultFusion slr fslr l sh) => VecList (Dim v2) (Fun m a (IO b)) -- ^ Vector of wrapped @m-@ary -- element-wise monadic zippers -> VecList m (UArray r l sh (v a)) -- ^ Vector of source arrays of vectors
Data/Yarr/Shape.hs view
@@ -12,6 +12,9 @@ -- * Specialized flow dim2BlockFill,++ -- * Touch functions+ Touchable(..), noTouch, ) where import Prelude as P hiding (foldl, foldr)
Data/Yarr/Utils/Fork.hs view
@@ -10,11 +10,12 @@ makeForkEachSlice :: (Shape sh, Arity n, v ~ VecList n)- => Int -- ^ Number of threads to fork work on- -> sh -- ^ Start- -> sh -- ^ End- -> v (Work sh a) -- ^ Slice works- -> (Int -> IO (v a)) -- ^ Thread work, returns piece of result for each slice+ => Int -- ^ Number of threads to fork the work on+ -> sh -- ^ Lower bound+ -> sh -- ^ Upper bound+ -> v (Work sh a) -- ^ Per-slice interval works+ -> (Int -> IO (v a)) -- ^ Producer of per-thread work,+ -- which returns piece of result for each slice {-# INLINE makeForkEachSlice #-} makeForkEachSlice threads start end rangeWorks = let {-# INLINE etWork #-}@@ -24,11 +25,11 @@ makeForkSlicesOnce :: (Shape sh, Arity n)- => Int -- ^ Number of threads to fork work on- -> VecList n (sh, sh) -- ^ (start, end) for each slice- -> VecList n (Work sh a) -- ^ Slice works- -> (Int -> IO [(Int, a)]) -- ^ Thread work, returns pieces of results:- -- [(slice number, result)]+ => Int -- ^ Number of threads to fork the work on+ -> VecList n (sh, sh) -- ^ (lower bound, upper bound) for each slice+ -> VecList n (Work sh a) -- ^ Per-slice interval works+ -> (Int -> IO [(Int, a)]) -- ^ Producer of per-thread work,+ -- which returns pieces of results: [(slice number, result)] {-# INLINE makeForkSlicesOnce #-} makeForkSlicesOnce !threads ranges rangeWorks = let !slices = V.length rangeWorks@@ -74,11 +75,11 @@ makeFork :: Shape sh- => Int -- ^ Number of threads to fork work on- -> sh -- ^ Start- -> sh -- ^ End- -> (Work sh a) -- ^ Work- -> (Int -> IO a) -- ^ Thread work+ => Int -- ^ Number of threads to fork the work on+ -> sh -- ^ Lower bound+ -> sh -- ^ Upper bound+ -> (Work sh a) -- ^ Interval work+ -> (Int -> IO a) -- ^ Producer of per-thread work {-# INLINE makeFork #-} makeFork chunks start end = let {-# INLINE chunkRange #-}
+ Data/Yarr/Walk.hs view
@@ -0,0 +1,274 @@++module Data.Yarr.Walk (+ -- * Fold combinators+ -- | See source of these 4 functions+ -- to construct more similar ones,+ -- if you need.+ reduceL, reduceLeftM,+ reduceR, reduceRightM,++ -- * Combinators to walk with mutable state+ -- | Added specially to improve performance+ -- of tasks like histogram filling.+ --+ -- Unfortunately, GHC doesn't figure that folding state+ -- isn't changed as ADT in such cases and doesn't lift+ -- it's evaluation higher from folding routine.+ mutate, imutate,++ -- * Walk runners+ walk, iwalk, rangeWalk,+ walkP, iwalkP, rangeWalkP,+ walkSlicesSeparate, iwalkSlicesSeparate, rangeWalkSlicesSeparate,+ walkSlicesSeparateP, iwalkSlicesSeparateP, rangeWalkSlicesSeparateP,++ -- * Aliases for walk types+ StatefulWalk, Foldl, Foldr,+) where++import Data.Yarr.Base+import Data.Yarr.Shape as S+import Data.Yarr.Eval++import Data.Yarr.Walk.Internal+++-- | /O(0)/+reduceLeftM+ :: Foldl i a b -- ^ 'S.foldl' or curried 'S.unrolledFoldl'+ -> (b -> a -> IO b) -- ^ Monadic left reduce+ -> StatefulWalk i a b -- ^ Result stateful walk to be passed+ -- to walk runners+{-# INLINE reduceLeftM #-}+reduceLeftM foldl rf = foldl (\b _ a -> rf b a)++-- | /O(0)/+reduceL+ :: Foldl i a b -- ^ 'S.foldl' or curried 'S.unrolledFoldl'+ -> (b -> a -> b) -- ^ Pure left reduce+ -> StatefulWalk i a b -- ^ Result stateful walk to be passed+ -- to walk runners+{-# INLINE reduceL #-}+reduceL foldl rf = foldl (\b _ a -> return $ rf b a)++-- | /O(0)/+reduceRightM+ :: Foldr i a b -- ^ 'S.foldr' or curried 'S.unrolledFoldr'+ -> (a -> b -> IO b) -- ^ Monadic right reduce+ -> StatefulWalk i a b -- ^ Result stateful walk to be passed+ -- to walk runners+{-# INLINE reduceRightM #-}+reduceRightM foldr rf = foldr (\_ a b -> rf a b)++-- | /O(0)/+reduceR+ :: Foldr i a b -- ^ 'S.foldr' or curried 'S.unrolledFoldr'+ -> (a -> b -> b) -- ^ Pure right reduce+ -> StatefulWalk i a b -- ^ Result stateful walk to be passed+ -- to walk runners+{-# INLINE reduceR #-}+reduceR foldr rf = foldr (\_ a b -> return $ rf a b)+++-- | /O(0)/+mutate+ :: Fill i a -- ^ 'S.fill' or curried 'S.unrolledFill'.+ -- If mutating is associative,+ -- 'S.dim2BlockFill' is also acceptable.+ -> (s -> a -> IO ()) -- ^ (state -> array element -> (state has changed))+ -- -- State mutating function+ -> StatefulWalk i a s -- ^ Result stateful walk to be passed+ -- to walk runners+{-# INLINE mutate #-}+mutate fill mf = imutate fill (\s i -> mf s)++-- | /O(0)/ Version of 'mutate', accepts mutating function+-- which additionaly accepts array index.+imutate+ :: Fill i a -- ^ 'S.fill' or curried 'S.unrolledFill'.+ -- If mutating is associative,+ -- 'S.dim2BlockFill' is also acceptable.+ -> (s -> i -> a -> IO ()) -- ^ Indexed state mutating function+ -> StatefulWalk i a s -- ^ Result stateful walk to be passed+ -- to walk runners+{-# INLINE imutate #-}+imutate fill imf ms index start end = do+ s <- ms+ fill index (imf s) start end+ return s++++-- | /O(n)/ Walk with state,+-- with non-indexed function ('reduceL' group of fold combinators, 'mutate').+--+-- Example:+--+-- @'Data.Yarr.IO.List.toList' = walk ('reduceR' 'S.foldr' (:)) (return [])@+walk+ :: (USource r l sh a, PreferredWorkIndex l sh i)+ => StatefulWalk i a s -- ^ Stateful walking function+ -> IO s -- ^ Monadic initial state (fold zero).+ -- Wrap pure state in 'return'.+ -> UArray r l sh a -- ^ Source array+ -> IO s -- ^ Final state (fold result)+{-# INLINE walk #-}+walk = anyWalk++-- | /O(n)/ Walk with state,+-- with indexed function ('S.foldl', 'S.foldr', 'imutate', etc).+--+-- Example:+--+-- @res \<- iwalk ('S.foldl' (\\s i a -> ...)) foldZero sourceArray@+iwalk+ :: USource r l sh a+ => StatefulWalk sh a s -- ^ Stateful walking function+ -> IO s -- ^ Monadic initial state (fold zero).+ -- Wrap pure state in 'return'.+ -> UArray r l sh a -- ^ Source array+ -> IO s -- ^ Final state (fold result)+{-# INLINE iwalk #-}+iwalk = anyWalk++-- | /O(n)/ Walk with state, in specified range of indices.+rangeWalk+ :: USource r l sh a+ => StatefulWalk sh a s -- ^ Stateful walking function+ -> IO s -- ^ Monadic initial state (fold zero).+ -- Wrap pure state in 'return'.+ -> UArray r l sh a -- ^ Source array+ -> sh -- ^ Top-left+ -> sh -- ^ and bottom-right corners of range to walk in+ -> IO s -- ^ Final state (fold result)+{-# INLINE rangeWalk #-}+rangeWalk = anyRangeWalk+++-- | /O(n)/ Run associative non-indexed stateful walk, in parallel.+--+-- Example -- associative image histogram filling in the test:+-- <https://github.com/leventov/yarr/blob/master/tests/lum-equalization.hs>+walkP+ :: (USource r l sh a, PreferredWorkIndex l sh i)+ => Threads -- ^ Number of threads to parallelize walk on+ -> StatefulWalk i a s -- ^ Associative stateful walking function+ -> IO s -- ^ Monadic zero state.+ -- Wrap pure state in 'return'.+ -> (s -> s -> IO s) -- ^ Associative monadic state joining function+ -> UArray r l sh a -- ^ Source array+ -> IO s -- ^ Gathered state (fold result)+{-# INLINE walkP #-}+walkP = anyWalkP++-- | /O(n)/ Run associative indexed stateful walk, in parallel.+iwalkP+ :: USource r l sh a+ => Threads -- ^ Number of threads to parallelize walk on+ -> StatefulWalk sh a s -- ^ Associative stateful walking function+ -> IO s -- ^ Monadic zero state.+ -- Wrap pure state in 'return'.+ -> (s -> s -> IO s) -- ^ Associative monadic state joining function+ -> UArray r l sh a -- ^ Source array+ -> IO s -- ^ Gathered state (fold result)+{-# INLINE iwalkP #-}+iwalkP = anyWalkP++-- | /O(n)/ Run associative stateful walk in specified range, in parallel.+rangeWalkP+ :: USource r l sh a+ => Threads -- ^ Number of threads to parallelize walk on+ -> StatefulWalk sh a s -- ^ Associative stateful walking function+ -> IO s -- ^ Monadic zero state.+ -- Wrap pure state in 'return'.+ -> (s -> s -> IO s) -- ^ Associative monadic state joining function+ -> UArray r l sh a -- ^ Source array+ -> sh -- ^ Top-left+ -> sh -- ^ and bottom-right corners of range to walk in+ -> IO s -- ^ Gathered state (fold result)+{-# INLINE rangeWalkP #-}+rangeWalkP = anyRangeWalkP+++-- | /O(n)/ Walk with state, with non-indexed function,+-- over each slice of array of vectors.+walkSlicesSeparate+ :: (UVecSource r slr l sh v e, PreferredWorkIndex l sh i)+ => StatefulWalk i e s -- ^ Stateful slice-wise walking function+ -> IO s -- ^ Monadic initial state (fold zero).+ -- Wrap pure state in 'return'.+ -> UArray r l sh (v e) -- ^ Source array of vectors+ -> IO (VecList (Dim v) s) -- ^ Vector of final states (fold results)+{-# INLINE walkSlicesSeparate #-}+walkSlicesSeparate = anyWalkSlicesSeparate++-- | /O(n)/ Walk with state, with indexed function,+-- over each slice of array of vectors.+iwalkSlicesSeparate+ :: UVecSource r slr l sh v e+ => StatefulWalk sh e s -- ^ Stateful slice-wise walking function+ -> IO s -- ^ Monadic initial state (fold zero).+ -- Wrap pure state in 'return'.+ -> UArray r l sh (v e) -- ^ Source array of vectors+ -> IO (VecList (Dim v) s) -- ^ Vector of final states (fold results)+{-# INLINE iwalkSlicesSeparate #-}+iwalkSlicesSeparate = anyWalkSlicesSeparate++-- | /O(n)/ Walk with state, in specified range of indices,+-- over each slice of array of vectors.+rangeWalkSlicesSeparate+ :: UVecSource r slr l sh v e+ => StatefulWalk sh e s -- ^ Stateful slice-wise walking function+ -> IO s -- ^ Monadic initial state (fold zero).+ -- Wrap pure state in 'return'.+ -> UArray r l sh (v e) -- ^ Source array of vectors+ -> sh -- ^ Top-left+ -> sh -- ^ and bottom-right corners of range to walk in+ -> IO (VecList (Dim v) s) -- ^ Vector of final states (fold results)+{-# INLINE rangeWalkSlicesSeparate #-}+rangeWalkSlicesSeparate = anyRangeWalkSlicesSeparate+++-- | /O(n)/ Run associative non-indexed stateful walk+-- over slices of array of vectors, in parallel.+walkSlicesSeparateP+ :: (UVecSource r slr l sh v e, PreferredWorkIndex l sh i)+ => Threads -- ^ Number of threads to parallelize walk on+ -> StatefulWalk i e s -- ^ Stateful slice-wise walking function+ -> IO s -- ^ Monadic zero state.+ -- Wrap pure state in 'return'.+ -> (s -> s -> IO s) -- ^ Associative monadic state joining function+ -> UArray r l sh (v e) -- ^ Source array of vectors+ -> IO (VecList (Dim v) s) -- ^ Vector of gathered per slice results+{-# INLINE walkSlicesSeparateP #-}+walkSlicesSeparateP = anyWalkSlicesSeparateP++-- | /O(n)/ Run associative indexed stateful walk+-- over slices of array of vectors, in parallel.+iwalkSlicesSeparateP+ :: UVecSource r slr l sh v e+ => Threads -- ^ Number of threads to parallelize walk on+ -> StatefulWalk sh e s -- ^ Stateful slice-wise walking function+ -> IO s -- ^ Monadic zero state.+ -- Wrap pure state in 'return'.+ -> (s -> s -> IO s) -- ^ Associative monadic state joining function+ -> UArray r l sh (v e) -- ^ Source array of vectors+ -> IO (VecList (Dim v) s) -- ^ Vector of gathered per slice results+{-# INLINE iwalkSlicesSeparateP #-}+iwalkSlicesSeparateP = anyWalkSlicesSeparateP++-- | /O(n)/ Run associative stateful walk in specified range,+-- over slices of array of vectors, in parallel.+rangeWalkSlicesSeparateP+ :: UVecSource r slr l sh v e+ => Threads -- ^ Number of threads to parallelize walk on+ -> StatefulWalk sh e s -- ^ Stateful slice-wise walking function+ -> IO s -- ^ Monadic zero state.+ -- Wrap pure state in 'return'.+ -> (s -> s -> IO s) -- ^ Associative monadic state joining function+ -> UArray r l sh (v e) -- ^ Source array of vectors+ -> sh -- ^ Top-left+ -> sh -- ^ and bottom-right corners of range to walk in+ -> IO (VecList (Dim v) s) -- ^ Vector of gathered per slice results+{-# INLINE rangeWalkSlicesSeparateP #-}+rangeWalkSlicesSeparateP = anyRangeWalkSlicesSeparateP
+ Data/Yarr/Walk/Internal.hs view
@@ -0,0 +1,135 @@++module Data.Yarr.Walk.Internal where++import Prelude as P+import Control.Monad as M+import Data.List (groupBy)+import Data.Function (on)++import Data.Yarr.Base+import Data.Yarr.Shape as S+import Data.Yarr.Eval++import Data.Yarr.Utils.FixedVector as V hiding (toList)+import Data.Yarr.Utils.Fork+import Data.Yarr.Utils.Parallel+++anyWalk+ :: (USource r l sh a, WorkIndex sh i)+ => StatefulWalk i a s+ -> IO s+ -> UArray r l sh a+ -> IO s+{-# INLINE anyWalk #-}+anyWalk fold mz arr = anyRangeWalk fold mz arr zero (gsize arr)++anyRangeWalk+ :: (USource r l sh a, WorkIndex sh i)+ => StatefulWalk i a s+ -> IO s+ -> UArray r l sh a+ -> i -> i+ -> IO s+{-# INLINE anyRangeWalk #-}+anyRangeWalk fold mz arr start end = do+ force arr+ res <- fold mz (gindex arr) start end+ touchArray arr+ return res+++anyWalkP+ :: (USource r l sh a, WorkIndex sh i)+ => Threads+ -> StatefulWalk i a s+ -> IO s+ -> (s -> s -> IO s)+ -> UArray r l sh a+ -> IO s+{-# INLINE anyWalkP #-}+anyWalkP threads fold mz join arr =+ anyRangeWalkP threads fold mz join arr zero (gsize arr)++anyRangeWalkP+ :: (USource r l sh a, WorkIndex sh i)+ => Threads+ -> StatefulWalk i a s+ -> IO s+ -> (s -> s -> IO s)+ -> UArray r l sh a+ -> i -> i+ -> IO s+{-# INLINE anyRangeWalkP #-}+anyRangeWalkP threads fold mz join arr start end = do+ force arr+ ts <- threads+ (r:rs) <- parallel ts $+ makeFork ts start end (fold mz (gindex arr))+ touchArray arr++ M.foldM join r rs+++anyWalkSlicesSeparate+ :: (UVecSource r slr l sh v e, WorkIndex sh i)+ => StatefulWalk i e s+ -> IO s+ -> UArray r l sh (v e)+ -> IO (VecList (Dim v) s)+{-# INLINE anyWalkSlicesSeparate #-}+anyWalkSlicesSeparate fold mz arr =+ anyRangeWalkSlicesSeparate fold mz arr zero (gsize arr)++anyRangeWalkSlicesSeparate+ :: (UVecSource r slr l sh v e, WorkIndex sh i)+ => StatefulWalk i e s+ -> IO s+ -> UArray r l sh (v e)+ -> i -> i+ -> IO (VecList (Dim v) s)+{-# INLINE anyRangeWalkSlicesSeparate #-}+anyRangeWalkSlicesSeparate fold mz arr start end = do+ force arr+ rs <- V.mapM (\sl -> anyRangeWalk fold mz sl start end) (slices arr)+ touchArray arr+ return rs++anyWalkSlicesSeparateP+ :: (UVecSource r slr l sh v e, WorkIndex sh i)+ => Threads+ -> StatefulWalk i e s+ -> IO s+ -> (s -> s -> IO s)+ -> UArray r l sh (v e)+ -> IO (VecList (Dim v) s)+{-# INLINE anyWalkSlicesSeparateP #-}+anyWalkSlicesSeparateP threads fold mz join arr =+ anyRangeWalkSlicesSeparateP threads fold mz join arr zero (gsize arr)++anyRangeWalkSlicesSeparateP+ :: (UVecSource r slr l sh v e, WorkIndex sh i)+ => Threads+ -> StatefulWalk i e s+ -> IO s+ -> (s -> s -> IO s)+ -> UArray r l sh (v e)+ -> i -> i+ -> IO (VecList (Dim v) s)+{-# INLINE anyRangeWalkSlicesSeparateP #-}+anyRangeWalkSlicesSeparateP threads fold mz join arr start end = do+ force arr+ let sls = slices arr+ V.mapM force sls++ ts <- threads+ trs <- parallel ts $+ makeForkSlicesOnce+ ts+ (V.replicate (start, end))+ (V.map (\sl -> fold mz (gindex sl)) sls)+ touchArray arr++ let rsBySlices = P.map (P.map snd) $ groupBy ((==) `on` fst) $ concat trs+ rs <- M.mapM (\(r:rs) -> M.foldM join r rs) rsBySlices+ return (VecList rs)
− Data/Yarr/Work.hs
@@ -1,270 +0,0 @@--module Data.Yarr.Work (- -- * Fold combinators- -- | See source of these 4 functions- -- to construct more similar ones,- -- if you need.- reduceL, reduceLeftM,- reduceR, reduceRightM,-- -- * Combinators to work with mutable state- -- | Added specially to improve performance- -- of tasks like histogram filling.- --- -- Unfortunately, GHC doesn't figure that folding state- -- isn't changed as ADT in such cases and doesn't lift- -- it's evaluation higher from folding routine.- mutate, imutate,-- -- * Work runners- work, iwork, rangeWork,- workP, iworkP, rangeWorkP,- workOnSlicesSeparate, iworkOnSlicesSeparate, rangeWorkOnSlicesSeparate,- workOnSlicesSeparateP, iworkOnSlicesSeparateP, rangeWorkOnSlicesSeparateP,-- -- * Aliases for work types- StatefulWork, Foldl, Foldr,-) where--import Data.Yarr.Base-import Data.Yarr.Shape as S-import Data.Yarr.Eval--import Data.Yarr.Work.Internal----- | /O(0)/-reduceLeftM- :: Foldl i a b -- ^ 'S.foldl' or curried 'S.unrolledFoldl'- -> (b -> a -> IO b) -- ^ Monadic left reduce- -> StatefulWork i a b -- ^ Result stateful work to be passed- -- to work runners-{-# INLINE reduceLeftM #-}-reduceLeftM foldl rf = foldl (\b _ a -> rf b a)---- | /O(0)/-reduceL- :: Foldl i a b -- ^ 'S.foldl' or curried 'S.unrolledFoldl'- -> (b -> a -> b) -- ^ Pure left reduce- -> StatefulWork i a b -- ^ Result stateful work to be passed- -- to work runners-{-# INLINE reduceL #-}-reduceL foldl rf = foldl (\b _ a -> return $ rf b a)---- | /O(0)/-reduceRightM- :: Foldr i a b -- ^ 'S.foldr' or curried 'S.unrolledFoldr'- -> (a -> b -> IO b) -- ^ Monadic right reduce- -> StatefulWork i a b -- ^ Result stateful work to be passed- -- to work runners-{-# INLINE reduceRightM #-}-reduceRightM foldr rf = foldr (\_ a b -> rf a b)---- | /O(0)/-reduceR- :: Foldr i a b -- ^ 'S.foldr' or curried 'S.unrolledFoldr'- -> (a -> b -> b) -- ^ Pure right reduce- -> StatefulWork i a b -- ^ Result stateful work to be passed- -- to work runners-{-# INLINE reduceR #-}-reduceR foldr rf = foldr (\_ a b -> return $ rf a b)----- | /O(0)/-mutate- :: Fill i a -- ^ 'S.fill' or curried 'S.unrolledFill'.- -- If mutating is associative,- -- 'S.dim2BlockFill' is also acceptable.- -> (s -> a -> IO ()) -- ^ (state -> array element -> (state has changed))- -- -- State mutating function- -> StatefulWork i a s -- ^ Result stateful work to be passed- -- to work runners-{-# INLINE mutate #-}-mutate fill mf = imutate fill (\s i -> mf s)---- | /O(0)/ Version of 'mutate', accepts mutating function--- which additionaly accepts array index.-imutate- :: Fill i a -- ^ 'S.fill' or curried 'S.unrolledFill'.- -- If mutating is associative,- -- 'S.dim2BlockFill' is also acceptable.- -> (s -> i -> a -> IO ()) -- ^ Indexed state mutating function- -> StatefulWork i a s -- ^ Result stateful work to be passed- -- to work runners-{-# INLINE imutate #-}-imutate fill imf ms index start end = do- s <- ms- fill index (imf s) start end- return s------ | /O(n)/ Run non-indexed stateful work.------ Example:------ @'Data.Yarr.IO.List.toList' = work ('reduceR' 'S.foldr' (:)) (return [])@-work- :: (USource r l sh a, PreferredWorkIndex l sh i)- => StatefulWork i a s -- ^ Stateful working function- -> IO s -- ^ Monadic initial state (fold zero).- -- Wrap pure state in 'return'.- -> UArray r l sh a -- ^ Source array- -> IO s -- ^ Final state (fold result)-{-# INLINE work #-}-work = anyWork---- | /O(n)/ Run indexed stateful work.------ Example:------ @res \<- iwork ('S.foldl' (\\s i a -> ...)) foldZero sourceArray@-iwork- :: USource r l sh a- => StatefulWork sh a s -- ^ Stateful working function- -> IO s -- ^ Monadic initial state (fold zero).- -- Wrap pure state in 'return'.- -> UArray r l sh a -- ^ Source array- -> IO s -- ^ Final state (fold result)-{-# INLINE iwork #-}-iwork = anyWork---- | /O(n)/ Run stateful work in specified range of indices.-rangeWork- :: USource r l sh a- => StatefulWork sh a s -- ^ Stateful working function- -> IO s -- ^ Monadic initial state (fold zero).- -- Wrap pure state in 'return'.- -> UArray r l sh a -- ^ Source array- -> sh -- ^ Top-left- -> sh -- ^ and bottom-right corners of range to work in- -> IO s -- ^ Final state (fold result)-{-# INLINE rangeWork #-}-rangeWork = anyRangeWork----- | /O(n)/ Run associative non-indexed stateful work in parallel.------ Example -- associative image histogram filling in the test:--- <https://github.com/leventov/yarr/blob/master/tests/lum-equalization.hs>-workP- :: (USource r l sh a, PreferredWorkIndex l sh i)- => Threads -- ^ Number of threads to parallelize work on- -> StatefulWork i a s -- ^ Associative stateful working function- -> IO s -- ^ Monadic zero state.- -- Wrap pure state in 'return'.- -> (s -> s -> IO s) -- ^ Associative monadic state joining function- -> UArray r l sh a -- ^ Source array- -> IO s -- ^ Gathered state (fold result)-{-# INLINE workP #-}-workP = anyWorkP---- | /O(n)/ Run associative indexed stateful work in parallel.-iworkP- :: USource r l sh a- => Threads -- ^ Number of threads to parallelize work on- -> StatefulWork sh a s -- ^ Associative stateful working function- -> IO s -- ^ Monadic zero state.- -- Wrap pure state in 'return'.- -> (s -> s -> IO s) -- ^ Associative monadic state joining function- -> UArray r l sh a -- ^ Source array- -> IO s -- ^ Gathered state (fold result)-{-# INLINE iworkP #-}-iworkP = anyWorkP---- | /O(n)/ Run associative stateful work in specified range in parallel.-rangeWorkP- :: USource r l sh a- => Threads -- ^ Number of threads to parallelize work on- -> StatefulWork sh a s -- ^ Associative stateful working function- -> IO s -- ^ Monadic zero state.- -- Wrap pure state in 'return'.- -> (s -> s -> IO s) -- ^ Associative monadic state joining function- -> UArray r l sh a -- ^ Source array- -> sh -- ^ Top-left- -> sh -- ^ and bottom-right corners of range to work in- -> IO s -- ^ Gathered state (fold result)-{-# INLINE rangeWorkP #-}-rangeWorkP = anyRangeWorkP----- | /O(n)/ Run non-indexed stateful work over each slice of array of vectors.-workOnSlicesSeparate- :: (UVecSource r slr l sh v e, PreferredWorkIndex l sh i)- => StatefulWork i e s -- ^ Stateful slice-wise working function- -> IO s -- ^ Monadic initial state (fold zero).- -- Wrap pure state in 'return'.- -> UArray r l sh (v e) -- ^ Source array of vectors- -> IO (VecList (Dim v) s) -- ^ Vector of final states (fold results)-{-# INLINE workOnSlicesSeparate #-}-workOnSlicesSeparate = anyWorkOnSlicesSeparate---- | /O(n)/ Run indexed stateful work over each slice of array of vectors.-iworkOnSlicesSeparate- :: UVecSource r slr l sh v e- => StatefulWork sh e s -- ^ Stateful slice-wise working function- -> IO s -- ^ Monadic initial state (fold zero).- -- Wrap pure state in 'return'.- -> UArray r l sh (v e) -- ^ Source array of vectors- -> IO (VecList (Dim v) s) -- ^ Vector of final states (fold results)-{-# INLINE iworkOnSlicesSeparate #-}-iworkOnSlicesSeparate = anyWorkOnSlicesSeparate---- | /O(n)/ Run stateful work in specified range--- over each slice of array of vectors.-rangeWorkOnSlicesSeparate- :: UVecSource r slr l sh v e- => StatefulWork sh e s -- ^ Stateful slice-wise working function- -> IO s -- ^ Monadic initial state (fold zero).- -- Wrap pure state in 'return'.- -> UArray r l sh (v e) -- ^ Source array of vectors- -> sh -- ^ Top-left- -> sh -- ^ and bottom-right corners of range to work in- -> IO (VecList (Dim v) s) -- ^ Vector of final states (fold results)-{-# INLINE rangeWorkOnSlicesSeparate #-}-rangeWorkOnSlicesSeparate = anyRangeWorkOnSlicesSeparate----- | /O(n)/ Run associative non-indexed stateful work--- over slices of array of vectors in parallel.-workOnSlicesSeparateP- :: (UVecSource r slr l sh v e, PreferredWorkIndex l sh i)- => Threads -- ^ Number of threads to parallelize work on- -> StatefulWork i e s -- ^ Stateful slice-wise working function- -> IO s -- ^ Monadic zero state.- -- Wrap pure state in 'return'.- -> (s -> s -> IO s) -- ^ Associative monadic state joining function- -> UArray r l sh (v e) -- ^ Source array of vectors- -> IO (VecList (Dim v) s) -- ^ Vector of gathered per slice results-{-# INLINE workOnSlicesSeparateP #-}-workOnSlicesSeparateP = anyWorkOnSlicesSeparateP---- | /O(n)/ Run associative indexed stateful work--- over slices of array of vectors in parallel.-iworkOnSlicesSeparateP- :: UVecSource r slr l sh v e- => Threads -- ^ Number of threads to parallelize work on- -> StatefulWork sh e s -- ^ Stateful slice-wise working function- -> IO s -- ^ Monadic zero state.- -- Wrap pure state in 'return'.- -> (s -> s -> IO s) -- ^ Associative monadic state joining function- -> UArray r l sh (v e) -- ^ Source array of vectors- -> IO (VecList (Dim v) s) -- ^ Vector of gathered per slice results-{-# INLINE iworkOnSlicesSeparateP #-}-iworkOnSlicesSeparateP = anyWorkOnSlicesSeparateP---- | /O(n)/ Run associative stateful work in specified range--- over slices of array of vectors in parallel.-rangeWorkOnSlicesSeparateP- :: UVecSource r slr l sh v e- => Threads -- ^ Number of threads to parallelize work on- -> StatefulWork sh e s -- ^ Stateful slice-wise working function- -> IO s -- ^ Monadic zero state.- -- Wrap pure state in 'return'.- -> (s -> s -> IO s) -- ^ Associative monadic state joining function- -> UArray r l sh (v e) -- ^ Source array of vectors- -> sh -- ^ Top-left- -> sh -- ^ and bottom-right corners of range to work in- -> IO (VecList (Dim v) s) -- ^ Vector of gathered per slice results-{-# INLINE rangeWorkOnSlicesSeparateP #-}-rangeWorkOnSlicesSeparateP = anyRangeWorkOnSlicesSeparateP
− Data/Yarr/Work/Internal.hs
@@ -1,135 +0,0 @@--module Data.Yarr.Work.Internal where--import Prelude as P-import Control.Monad as M-import Data.List (groupBy)-import Data.Function (on)--import Data.Yarr.Base-import Data.Yarr.Shape as S-import Data.Yarr.Eval--import Data.Yarr.Utils.FixedVector as V hiding (toList)-import Data.Yarr.Utils.Fork-import Data.Yarr.Utils.Parallel---anyWork- :: (USource r l sh a, WorkIndex sh i)- => StatefulWork i a s- -> IO s- -> UArray r l sh a- -> IO s-{-# INLINE anyWork #-}-anyWork fold mz arr = anyRangeWork fold mz arr zero (gsize arr)--anyRangeWork- :: (USource r l sh a, WorkIndex sh i)- => StatefulWork i a s- -> IO s- -> UArray r l sh a- -> i -> i- -> IO s-{-# INLINE anyRangeWork #-}-anyRangeWork fold mz arr start end = do- force arr- res <- fold mz (gindex arr) start end- touchArray arr- return res---anyWorkP- :: (USource r l sh a, WorkIndex sh i)- => Threads- -> StatefulWork i a s- -> IO s- -> (s -> s -> IO s)- -> UArray r l sh a- -> IO s-{-# INLINE anyWorkP #-}-anyWorkP threads fold mz join arr =- anyRangeWorkP threads fold mz join arr zero (gsize arr)--anyRangeWorkP- :: (USource r l sh a, WorkIndex sh i)- => Threads- -> StatefulWork i a s- -> IO s- -> (s -> s -> IO s)- -> UArray r l sh a- -> i -> i- -> IO s-{-# INLINE anyRangeWorkP #-}-anyRangeWorkP threads fold mz join arr start end = do- force arr- ts <- threads- (r:rs) <- parallel ts $- makeFork ts start end (fold mz (gindex arr))- touchArray arr-- M.foldM join r rs---anyWorkOnSlicesSeparate- :: (UVecSource r slr l sh v e, WorkIndex sh i)- => StatefulWork i e s- -> IO s- -> UArray r l sh (v e)- -> IO (VecList (Dim v) s)-{-# INLINE anyWorkOnSlicesSeparate #-}-anyWorkOnSlicesSeparate fold mz arr =- anyRangeWorkOnSlicesSeparate fold mz arr zero (gsize arr)--anyRangeWorkOnSlicesSeparate- :: (UVecSource r slr l sh v e, WorkIndex sh i)- => StatefulWork i e s- -> IO s- -> UArray r l sh (v e)- -> i -> i- -> IO (VecList (Dim v) s)-{-# INLINE anyRangeWorkOnSlicesSeparate #-}-anyRangeWorkOnSlicesSeparate fold mz arr start end = do- force arr- rs <- V.mapM (\sl -> anyRangeWork fold mz sl start end) (slices arr)- touchArray arr- return rs--anyWorkOnSlicesSeparateP- :: (UVecSource r slr l sh v e, WorkIndex sh i)- => Threads- -> StatefulWork i e s- -> IO s- -> (s -> s -> IO s)- -> UArray r l sh (v e)- -> IO (VecList (Dim v) s)-{-# INLINE anyWorkOnSlicesSeparateP #-}-anyWorkOnSlicesSeparateP threads fold mz join arr =- anyRangeWorkOnSlicesSeparateP threads fold mz join arr zero (gsize arr)--anyRangeWorkOnSlicesSeparateP- :: (UVecSource r slr l sh v e, WorkIndex sh i)- => Threads- -> StatefulWork i e s- -> IO s- -> (s -> s -> IO s)- -> UArray r l sh (v e)- -> i -> i- -> IO (VecList (Dim v) s)-{-# INLINE anyRangeWorkOnSlicesSeparateP #-}-anyRangeWorkOnSlicesSeparateP threads fold mz join arr start end = do- force arr- let sls = slices arr- V.mapM force sls-- ts <- threads- trs <- parallel ts $- makeForkSlicesOnce- ts- (V.replicate (start, end))- (V.map (\sl -> fold mz (gindex sl)) sls)- touchArray arr-- let rsBySlices = P.map (P.map snd) $ groupBy ((==) `on` fst) $ concat trs- rs <- M.mapM (\(r:rs) -> M.foldM join r rs) rsBySlices- return (VecList rs)
Data/Yarr/WorkTypes.hs view
@@ -1,15 +1,21 @@ module Data.Yarr.WorkTypes where --- | Generalizes interval works: 'Fill's, 'StatefulWork's.+-- | Abstracts interval works: 'Fill's, 'Walk's. -- -- To be passed to functions from "Data.Yarr.Utils.Fork" module--- and called directly.+-- or called directly. type Work sh a =- sh -- ^ Start (lower index)- -> sh -- ^ End (higher index)+ sh -- ^ Lower bound+ -> sh -- ^ Upper bound -> IO a -- ^ Result +-- | Curried version of 'StatefulWalk'. Identical to 'Work', indeed.+type Walk sh a =+ sh -- ^ Lower bound (start for left walks, end for right ones)+ -> sh -- ^ Upper bound (end or start)+ -> IO a -- ^ Result+ -- | Alias to frequently used get-write-from-to arguments combo. -- -- To be passed as 1st parameter of all 'Data.Yarr.Eval.Load'ing functions@@ -21,25 +27,25 @@ -- | Generalizes both partially applied left and right folds,--- as well as works on mutable state.+-- as well as walks with mutable state. ----- To be passed to fold runners from "Data.Yarr.Work" module.-type StatefulWork sh a s = +-- To be passed to walk runners from "Data.Yarr.Walk" module.+type StatefulWalk sh a s = IO s -- ^ Initial state -> (sh -> IO a) -- ^ Indexing function- -> Work sh s -- ^ Curried result function -- worker,+ -> Walk sh s -- ^ Curried result function -- walker, -- emits final state --- | Generalizes left to right folds.+-- | Generalizes left folds. ----- To be passed to fold combinators from "Data.Yarr.Work" module.+-- To be passed to fold combinators from "Data.Yarr.Walk" module. type Foldl sh a b = (b -> sh -> a -> IO b) -- ^ Generalized left reduce- -> StatefulWork sh a b -- ^ Curried result stateful work+ -> StatefulWalk sh a b -- ^ Curried result stateful walk --- | Generalizes right to left folds.+-- | Generalizes right folds. ----- To be passed to fold combinators from "Data.Yarr.Work" module.+-- To be passed to fold combinators from "Data.Yarr.Walk" module. type Foldr sh a b = (sh -> a -> b -> IO b) -- ^ Generalized right reduce- -> StatefulWork sh a b -- ^ Curried result stateful work+ -> StatefulWalk sh a b -- ^ Curried result stateful walk
yarr.cabal view
@@ -1,5 +1,5 @@ Name: yarr-Version: 1.2.3+Version: 1.3.1 Synopsis: Yet another array library Description: Yarr is a new blazing fast dataflow framework (array library),@@ -20,9 +20,15 @@ . Shortcoming by design: lack of pure indexing interface. .+ /Changes in 1.3 (ex. 0.9.3):/+ .+ * IFusion -- mapping/zipping with index+ .+ * Rename: Work -> Walk+ . /Changes in version 0.9.2:/ .- * Safe folds -- see "Data.Yarr.Work"+ * Safe folds -- see "Data.Yarr.Walk" . * Issue with slice-wise loading with unrolled filling function solved .@@ -58,7 +64,8 @@ TypeFamilies, MultiParamTypeClasses, FunctionalDependencies, FlexibleContexts, EmptyDataDecls,- FlexibleInstances, TypeSynonymInstances, UndecidableInstances,+ FlexibleInstances, TypeSynonymInstances,+ UndecidableInstances, OverlappingInstances, GeneralizedNewtypeDeriving, StandaloneDeriving, RankNTypes, ScopedTypeVariables, MagicHash, BangPatterns, UnboxedTuples,@@ -67,9 +74,10 @@ exposed-modules: Data.Yarr Data.Yarr.Base+ Data.Yarr.Fusion Data.Yarr.Eval Data.Yarr.Flow- Data.Yarr.Work+ Data.Yarr.Walk Data.Yarr.Shape Data.Yarr.Repr.Foreign Data.Yarr.Repr.Boxed@@ -82,7 +90,6 @@ Data.Yarr.Utils.Parallel Data.Yarr.Utils.Split Data.Yarr.Utils.Primitive- Data.Yarr.Utils.LowLevelFlow Debug.Yarr other-modules:@@ -101,5 +108,6 @@ -- re-exported in Data.Yarr.Shape Data.Yarr.WorkTypes - Data.Yarr.Work.Internal+ Data.Yarr.Walk.Internal Data.Yarr.Utils.Storable+ Data.Yarr.Utils.LowLevelFlow