accelerate 1.0.0.0 → 1.1.0.0
raw patch · 42 files changed
+4917/−2762 lines, 42 filesdep +th-lift-instances
Dependencies added: th-lift-instances
Files
- CHANGELOG.md +103/−0
- Data/Array/Accelerate.hs +5/−5
- Data/Array/Accelerate/AST.hs +485/−150
- Data/Array/Accelerate/Analysis/Hash.hs +506/−0
- Data/Array/Accelerate/Analysis/Hash/TH.hs +30/−0
- Data/Array/Accelerate/Analysis/Match.hs +28/−317
- Data/Array/Accelerate/Array/Data.hs +3/−0
- Data/Array/Accelerate/Array/Remote/LRU.hs +22/−16
- Data/Array/Accelerate/Array/Remote/Nursery.hs +12/−7
- Data/Array/Accelerate/Array/Remote/Table.hs +4/−1
- Data/Array/Accelerate/Array/Representation.hs +3/−5
- Data/Array/Accelerate/Array/Sugar.hs +14/−12
- Data/Array/Accelerate/Array/Unique.hs +4/−0
- Data/Array/Accelerate/Async.hs +1/−1
- Data/Array/Accelerate/Classes/Enum.hs +1/−0
- Data/Array/Accelerate/Classes/FromIntegral.hs +1/−0
- Data/Array/Accelerate/Classes/Integral.hs +1/−0
- Data/Array/Accelerate/Classes/Real.hs +1/−0
- Data/Array/Accelerate/Classes/RealFloat.hs +202/−16
- Data/Array/Accelerate/Classes/RealFrac.hs +2/−1
- Data/Array/Accelerate/Debug/Flags.hs +94/−56
- Data/Array/Accelerate/Debug/Monitoring.hs +192/−60
- Data/Array/Accelerate/Debug/Timed.hs +33/−8
- Data/Array/Accelerate/Interpreter.hs +266/−31
- Data/Array/Accelerate/Language.hs +161/−26
- Data/Array/Accelerate/Lifetime.hs +5/−0
- Data/Array/Accelerate/Prelude.hs +348/−245
- Data/Array/Accelerate/Pretty/Graphviz.hs +11/−13
- Data/Array/Accelerate/Pretty/Print.hs +11/−12
- Data/Array/Accelerate/Product.hs +1/−1
- Data/Array/Accelerate/Smart.hs +1918/−1598
- Data/Array/Accelerate/Trafo.hs +12/−2
- Data/Array/Accelerate/Trafo/Algebra.hs +4/−0
- Data/Array/Accelerate/Trafo/Base.hs +18/−16
- Data/Array/Accelerate/Trafo/Fusion.hs +42/−18
- Data/Array/Accelerate/Trafo/Sharing.hs +67/−24
- Data/Array/Accelerate/Trafo/Simplify.hs +11/−2
- Data/Array/Accelerate/Trafo/Substitution.hs +27/−2
- Data/Array/Accelerate/Type.hs +7/−17
- README.md +240/−0
- accelerate.cabal +21/−10
- changelog.md +0/−90
+ CHANGELOG.md view
@@ -0,0 +1,103 @@+# Change Log++Notable changes to the project will be documented in this file.++The format is based on [Keep a Changelog](http://keepachangelog.com/) and the+project adheres to the [Haskell Package Versioning+Policy (PVP)](https://pvp.haskell.org)++## [1.1.0.0] - 2017-09-21+### Added+ * Additional EKG monitoring hooks ([#340])+ * Operations from `RealFloat`++### Changed+ * Changed type of `scanl'`, `scanr'` to return an `Acc` tuple, rather than a+ tuple of `Acc` arrays.+ * Specialised folds `sum`, `product`, `minimum`, `maximum`, `and`, `or`,+ `any`, `all` now reduce along the innermost dimension only, rather than+ reducing all elements. You can recover the old behaviour by first+ `flatten`-ing the input array.+ * Add new stencil boundary condition `function`, to apply the given function+ to out-of-bounds indices.++### Fixed+ * [#390]: Wrong number of arguments in printf++## [1.0.0.0] - 2017-03-31+ * Many API and internal changes+ * Bug fixes and other enhancements++## [0.15.1.0]+ * Fix type of `allocateArray`++## [0.15.0.0]+ * Bug fixes and performance improvements.++## [0.14.0.0]+ * New iteration constructs.+ * Additional Prelude-like functions.+ * Improved code generation and fusion optimisation.+ * Concurrent kernel execution in the CUDA backend.+ * Bug fixes.++## [0.13.0.0]+ * New array fusion optimisation.+ * New foreign function interface for array and scalar expressions.+ * Additional Prelude-like functions.+ * New example programs.+ * Bug fixes and performance improvements.++## [0.12.0.0]+ * Full sharing recovery in scalar expressions and array computations.+ * Two new example applications in package `accelerate-examples` (both including a graphical frontend):+ * A real-time Canny edge detection + * An interactive fluid flow simulator+ * Bug fixes.++## [0.11.0.0]+ * New Prelude-like functions `zip*`, `unzip*`, `fill`, `enumFrom*`, `tail`,+ `init`, `drop`, `take`, `slit`, `gather*`, `scatter*`, and `shapeSize`.+ * New simplified AST (in package `accelerate-backend-kit`) for backend writers+ who want to avoid the complexities of the type-safe AST.++## [0.10.0.0]+ * Complete sharing recovery for scalar expressions (but currently disabled by default).+ * Also bug fixes in array sharing recovery and a few new convenience functions.++## [0.9.0.0]+ * Streaming computations+ * Precompilation+ * Repa-style array indices+ * Additional collective operations supported by the CUDA backend: `stencil`s,+ more `scan`s, rank-polymorphic `fold`, `generate`.+ * Conversions to other array formats+ * Bug fixes++## 0.8.1.0+ * Bug fixes and some performance tweaks.++## 0.8.0.0+ * More collective operations supported by the CUDA backend: `replicate`,+ `slice` and `foldSeg`. Frontend and interpreter support for `stencil`.+ * Bug fixes.++## [0.7.1.0]+ * Initial release of the CUDA backend+++[1.1.0.0]: https://github.com/AccelerateHS/accelerate/compare/1.0.0.0...1.1.0.0+[1.0.0.0]: https://github.com/AccelerateHS/accelerate/compare/0.15.1.0...1.0.0.0+[0.15.1.0]: https://github.com/AccelerateHS/accelerate/compare/0.15.0.0...0.15.1.0+[0.15.0.0]: https://github.com/AccelerateHS/accelerate/compare/0.14.0.0...0.15.0.0+[0.14.0.0]: https://github.com/AccelerateHS/accelerate/compare/0.13.0.0...0.14.0.0+[0.13.0.0]: https://github.com/AccelerateHS/accelerate/compare/0.12.0.0...0.13.0.0+[0.12.0.0]: https://github.com/AccelerateHS/accelerate/compare/0.11.0.0...0.12.0.0+[0.11.0.0]: https://github.com/AccelerateHS/accelerate/compare/0.10.0.0...0.11.0.0+[0.10.0.0]: https://github.com/AccelerateHS/accelerate/compare/0.9.0.0...0.10.0.0+[0.9.0.0]: https://github.com/AccelerateHS/accelerate/compare/0_8_1_0...0.9.0.0+[0.7.1.0]: https://github.com/AccelerateHS/accelerate/compare/0_6_0_0...0_7_1_0++[#340]: https://github.com/AccelerateHS/accelerate/issues/340+[#390]: https://github.com/AccelerateHS/accelerate/issues/390+
Data/Array/Accelerate.hs view
@@ -55,10 +55,6 @@ -- * <http://hackage.haskell.org/package/accelerate-llvm-ptx accelerate-llvm-ptx>: -- implementation supporting parallel execution on CUDA-capable NVIDIA GPUs. ----- * <http://hackage.haskell.org/package/accelerate-cuda accelerate-cuda>:--- an older implementation supporting parallel execution on CUDA-capable--- NVIDIA GPUs. /__NOTE:__ This backend is being deprecated in favour of @accelerate-llvm-ptx@./--- -- [/Examples:/] -- -- * The <http://hackage.haskell.org/package/accelerate-examples accelerate-examples>@@ -95,6 +91,9 @@ -- * <https://hackage.haskell.org/package/accelerate-fft accelerate-fft>: Fast -- Fourier transform, with FFI bindings to optimised implementations. --+-- * <https://hackage.haskell.org/package/accelerate-blas accelerate-blas>: BLAS+-- and LAPACK operations, with FFI bindings to optimised implementations.+-- -- * <https://hackage.haskell.org/package/accelerate-bignum accelerate-bignum>: -- Fixed-width large integer arithmetic. --@@ -261,7 +260,8 @@ stencil, stencil2, -- *** Stencil specification- Stencil, Boundary(..),+ Stencil, Boundary,+ clamp, mirror, wrap, function, -- *** Common stencil patterns Stencil3, Stencil5, Stencil7, Stencil9,
Data/Array/Accelerate/AST.hs view
@@ -5,6 +5,7 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-}@@ -90,7 +91,7 @@ -- * Accelerated array expressions PreOpenAfun(..), OpenAfun, PreAfun, Afun, PreOpenAcc(..), OpenAcc(..), Acc,- Stencil(..), StencilR(..),+ PreBoundary(..), Boundary, Stencil(..), StencilR(..), -- * Accelerated sequences -- PreOpenSeq(..), Seq,@@ -104,21 +105,41 @@ NFDataAcc, rnfPreOpenAfun, rnfPreOpenAcc, rnfPreOpenFun, rnfPreOpenExp, + -- TemplateHaskell+ LiftAcc,+ liftIdx, liftTupleIdx, liftArrays,+ liftConst, liftSliceIndex, liftPrimConst, liftPrimFun,+ liftPreOpenAfun, liftPreOpenAcc, liftPreOpenFun, liftPreOpenExp,+ -- debugging showPreAccOp, showPreExpOp, ) where --standard library+import Control.DeepSeq import Data.List import Data.Typeable-import Control.DeepSeq+import Foreign.ForeignPtr+import Foreign.Marshal+import Foreign.Ptr+import Foreign.Storable+import GHC.Ptr ( Ptr(..) )+import System.IO.Unsafe+import Language.Haskell.TH ( Q, TExp )+import qualified Language.Haskell.TH as TH+import qualified Language.Haskell.TH.Syntax as TH+#if __GLASGOW_HASKELL__ <= 708+import Instances.TH.Lift () -- Int8, Int16...+#endif -- friends-import Data.Array.Accelerate.Type+import Data.Array.Accelerate.Array.Data+import Data.Array.Accelerate.Array.Representation ( SliceIndex(..), size )+import Data.Array.Accelerate.Array.Sugar hiding ( size )+import Data.Array.Accelerate.Array.Unique import Data.Array.Accelerate.Product-import Data.Array.Accelerate.Array.Representation ( SliceIndex(..) )-import Data.Array.Accelerate.Array.Sugar as Sugar+import Data.Array.Accelerate.Type #if __GLASGOW_HASKELL__ < 800 import Data.Array.Accelerate.Error #endif@@ -175,7 +196,7 @@ -- Projection of a value from a valuation of array elements using a de Bruijn index -- prjElt :: Idx env t -> ValElt env -> t-prjElt ZeroIdx (PushElt _ v) = Sugar.toElt v+prjElt ZeroIdx (PushElt _ v) = toElt v prjElt (SuccIdx idx) (PushElt val _) = prjElt idx val #if __GLASGOW_HASKELL__ < 800 prjElt _ _ = $internalError "prjElt" "inconsistent valuation"@@ -470,22 +491,19 @@ -- Map a stencil over an array. In contrast to 'map', the domain of a stencil function is an -- entire /neighbourhood/ of each array element. Stencil :: (Elt e, Elt e', Stencil sh e stencil)- => PreFun acc aenv (stencil -> e') -- stencil function- -> Boundary (EltRepr e) -- boundary condition- -> acc aenv (Array sh e) -- source array- -> PreOpenAcc acc aenv (Array sh e')+ => PreFun acc aenv (stencil -> e') -- stencil function+ -> PreBoundary acc aenv (Array sh e) -- boundary condition+ -> acc aenv (Array sh e) -- source array+ -> PreOpenAcc acc aenv (Array sh e') -- Map a binary stencil over an array.- Stencil2 :: (Elt e1, Elt e2, Elt e',- Stencil sh e1 stencil1,- Stencil sh e2 stencil2)- => PreFun acc aenv (stencil1 ->- stencil2 -> e') -- stencil function- -> Boundary (EltRepr e1) -- boundary condition #1- -> acc aenv (Array sh e1) -- source array #1- -> Boundary (EltRepr e2) -- boundary condition #2- -> acc aenv (Array sh e2) -- source array #2- -> PreOpenAcc acc aenv (Array sh e')+ Stencil2 :: (Elt a, Elt b, Elt c, Stencil sh a stencil1, Stencil sh b stencil2)+ => PreFun acc aenv (stencil1 -> stencil2 -> c) -- stencil function+ -> PreBoundary acc aenv (Array sh a) -- boundary condition #1+ -> acc aenv (Array sh a) -- source array #1+ -> PreBoundary acc aenv (Array sh b) -- boundary condition #2+ -> acc aenv (Array sh b) -- source array #2+ -> PreOpenAcc acc aenv (Array sh c) -- A sequence of operations. -- Collect :: Arrays arrs@@ -610,28 +628,52 @@ --} --- |Operations on stencils.+-- | Vanilla stencil boundary condition --+type Boundary = PreBoundary OpenAcc++-- | Boundary condition specification for stencil operations+--+data PreBoundary (acc :: * -> * -> *) aenv t where+ -- Clamp coordinates to the extent of the array+ Clamp :: PreBoundary acc aenv t++ -- Mirror coordinates beyond the array extent+ Mirror :: PreBoundary acc aenv t++ -- Wrap coordinates around on each dimension+ Wrap :: PreBoundary acc aenv t++ -- Use a constant value for outlying coordinates+ Constant :: Elt e+ => EltRepr e+ -> PreBoundary acc aenv (Array sh e)++ -- Apply the given function to outlying coordinates+ Function :: (Shape sh, Elt e)+ => PreFun acc aenv (sh -> e)+ -> PreBoundary acc aenv (Array sh e)+++-- | Operations on stencils+-- class (Shape sh, Elt e, IsTuple stencil, Elt stencil) => Stencil sh e stencil where- stencil :: StencilR sh e stencil- stencilAccess :: (sh -> e) -> sh -> stencil+ stencil :: StencilR sh e stencil --- |GADT reifying the 'Stencil' class.+-- | GADT reifying the 'Stencil' class -- data StencilR sh e pat where- StencilRunit3 :: (Elt e)- => StencilR DIM1 e (e,e,e)- StencilRunit5 :: (Elt e)- => StencilR DIM1 e (e,e,e,e,e)- StencilRunit7 :: (Elt e)- => StencilR DIM1 e (e,e,e,e,e,e,e)- StencilRunit9 :: (Elt e)- => StencilR DIM1 e (e,e,e,e,e,e,e,e,e)+ StencilRunit3 :: Elt e => StencilR DIM1 e (e,e,e)+ StencilRunit5 :: Elt e => StencilR DIM1 e (e,e,e,e,e)+ StencilRunit7 :: Elt e => StencilR DIM1 e (e,e,e,e,e,e,e)+ StencilRunit9 :: Elt e => StencilR DIM1 e (e,e,e,e,e,e,e,e,e)+ StencilRtup3 :: (Shape sh, Elt e) => StencilR sh e pat1 -> StencilR sh e pat2 -> StencilR sh e pat3 -> StencilR (sh:.Int) e (pat1,pat2,pat3)+ StencilRtup5 :: (Shape sh, Elt e) => StencilR sh e pat1 -> StencilR sh e pat2@@ -639,6 +681,7 @@ -> StencilR sh e pat4 -> StencilR sh e pat5 -> StencilR (sh:.Int) e (pat1,pat2,pat3,pat4,pat5)+ StencilRtup7 :: (Shape sh, Elt e) => StencilR sh e pat1 -> StencilR sh e pat2@@ -648,6 +691,7 @@ -> StencilR sh e pat6 -> StencilR sh e pat7 -> StencilR (sh:.Int) e (pat1,pat2,pat3,pat4,pat5,pat6,pat7)+ StencilRtup9 :: (Shape sh, Elt e) => StencilR sh e pat1 -> StencilR sh e pat2@@ -661,91 +705,40 @@ -> StencilR (sh:.Int) e (pat1,pat2,pat3,pat4,pat5,pat6,pat7,pat8,pat9) --- NB: We cannot start with 'DIM0'. The 'IsTuple stencil' superclass would at 'DIM0' imply that--- the types of individual array elements are in 'IsTuple'. (That would only possible if we--- could have (degenerate) 1-tuple, but we can't as we can't distinguish between a 1-tuple of a--- pair and a simple pair.) Hence, we need to start from 'DIM1' and use 'sh:.Int:.Int' in the--- recursive case (to avoid overlapping instances).+-- Note: [Stencil reification class]+--+-- We cannot start with 'DIM0'. The 'IsTuple stencil' superclass would at+-- 'DIM0' imply that the types of individual array elements are in 'IsTuple'.+-- (That would only possible if we could have (degenerate) 1-tuple, but we can't+-- as we can't distinguish between a 1-tuple of a pair and a simple pair.)+-- Hence, we need to start from 'DIM1' and use 'sh:.Int:.Int' in the recursive+-- case (to avoid overlapping instances). -- DIM1 instance Elt e => Stencil DIM1 e (e, e, e) where stencil = StencilRunit3- stencilAccess rf (Z:.y) = (rf' (y - 1),- rf' y ,- rf' (y + 1))- where- rf' d = rf (Z:.d) instance Elt e => Stencil DIM1 e (e, e, e, e, e) where stencil = StencilRunit5- stencilAccess rf (Z:.y) = (rf' (y - 2),- rf' (y - 1),- rf' y ,- rf' (y + 1),- rf' (y + 2))- where- rf' d = rf (Z:.d)+ instance Elt e => Stencil DIM1 e (e, e, e, e, e, e, e) where stencil = StencilRunit7- stencilAccess rf (Z:.y) = (rf' (y - 3),- rf' (y - 2),- rf' (y - 1),- rf' y ,- rf' (y + 1),- rf' (y + 2),- rf' (y + 3))- where- rf' d = rf (Z:.d)+ instance Elt e => Stencil DIM1 e (e, e, e, e, e, e, e, e, e) where stencil = StencilRunit9- stencilAccess rf (Z:.y) = (rf' (y - 4),- rf' (y - 3),- rf' (y - 2),- rf' (y - 1),- rf' y ,- rf' (y + 1),- rf' (y + 2),- rf' (y + 3),- rf' (y + 4))- where- rf' d = rf (Z:.d) --- DIM(n+1), where n>0+-- DIM(n+1), where n>1 instance (Stencil (sh:.Int) a row1, Stencil (sh:.Int) a row2, Stencil (sh:.Int) a row3) => Stencil (sh:.Int:.Int) a (row1, row2, row3) where stencil = StencilRtup3 stencil stencil stencil- stencilAccess rf xi = (stencilAccess (rf' (i - 1)) ix,- stencilAccess (rf' i ) ix,- stencilAccess (rf' (i + 1)) ix) - where- -- Invert then re-invert to ensure each recursive step gets a shape in the- -- standard scoc (right-recursive) ordering- --- ix' :. i = invertShape xi- ix = invertShape ix'-- -- Inject this dimension innermost- --- rf' d ds = rf $ invertShape (invertShape ds :. d)-- instance (Stencil (sh:.Int) a row1, Stencil (sh:.Int) a row2, Stencil (sh:.Int) a row3, Stencil (sh:.Int) a row4, Stencil (sh:.Int) a row5) => Stencil (sh:.Int:.Int) a (row1, row2, row3, row4, row5) where stencil = StencilRtup5 stencil stencil stencil stencil stencil- stencilAccess rf xi = (stencilAccess (rf' (i - 2)) ix,- stencilAccess (rf' (i - 1)) ix,- stencilAccess (rf' i ) ix,- stencilAccess (rf' (i + 1)) ix,- stencilAccess (rf' (i + 2)) ix)- where- ix' :. i = invertShape xi- ix = invertShape ix'- rf' d ds = rf $ invertShape (invertShape ds :. d) instance (Stencil (sh:.Int) a row1, Stencil (sh:.Int) a row2,@@ -756,17 +749,6 @@ Stencil (sh:.Int) a row7) => Stencil (sh:.Int:.Int) a (row1, row2, row3, row4, row5, row6, row7) where stencil = StencilRtup7 stencil stencil stencil stencil stencil stencil stencil- stencilAccess rf xi = (stencilAccess (rf' (i - 3)) ix,- stencilAccess (rf' (i - 2)) ix,- stencilAccess (rf' (i - 1)) ix,- stencilAccess (rf' i ) ix,- stencilAccess (rf' (i + 1)) ix,- stencilAccess (rf' (i + 2)) ix,- stencilAccess (rf' (i + 3)) ix)- where- ix' :. i = invertShape xi- ix = invertShape ix'- rf' d ds = rf $ invertShape (invertShape ds :. d) instance (Stencil (sh:.Int) a row1, Stencil (sh:.Int) a row2,@@ -779,39 +761,8 @@ Stencil (sh:.Int) a row9) => Stencil (sh:.Int:.Int) a (row1, row2, row3, row4, row5, row6, row7, row8, row9) where stencil = StencilRtup9 stencil stencil stencil stencil stencil stencil stencil stencil stencil- stencilAccess rf xi = (stencilAccess (rf' (i - 4)) ix,- stencilAccess (rf' (i - 3)) ix,- stencilAccess (rf' (i - 2)) ix,- stencilAccess (rf' (i - 1)) ix,- stencilAccess (rf' i ) ix,- stencilAccess (rf' (i + 1)) ix,- stencilAccess (rf' (i + 2)) ix,- stencilAccess (rf' (i + 3)) ix,- stencilAccess (rf' (i + 4)) ix)- where- ix' :. i = invertShape xi- ix = invertShape ix'- rf' d ds = rf $ invertShape (invertShape ds :. d) --- For stencilAccess to match how the user draws the stencil in code as a series--- of nested tuples, we need to recurse from the left. That is, we desire the--- following 2D stencil to represent elements to the top, bottom, left, and--- right of the focus as follows:------ stencil2D ( (_, t, _)--- , (l, _, r)--- , (_, b, _) ) = ...------ This function is used to reverse all components of a shape so that the--- innermost component, now the head, can be picked off.------ ...but needing to go via lists is unfortunate.----invertShape :: Shape sh => sh -> sh-invertShape = listToShape . reverse . shapeToList-- -- Embedded expressions -- -------------------- @@ -1064,8 +1015,9 @@ -- PrimProperFraction :: FloatingType a -> IntegralType b -> PrimFun (a -> (b, a)) -- operators from RealFloat- PrimIsNaN :: FloatingType a -> PrimFun (a -> Bool)- PrimAtan2 :: FloatingType a -> PrimFun ((a, a) -> a)+ PrimAtan2 :: FloatingType a -> PrimFun ((a, a) -> a)+ PrimIsNaN :: FloatingType a -> PrimFun (a -> Bool)+ PrimIsInfinite :: FloatingType a -> PrimFun (a -> Bool) -- PrimFloatRadix :: FloatingType a -> PrimFun (a -> Int) -- Integer? -- PrimFloatDigits :: FloatingType a -> PrimFun (a -> Int) -- PrimFloatRange :: FloatingType a -> PrimFun (a -> (Int, Int))@@ -1074,7 +1026,6 @@ -- PrimExponent :: FloatingType a -> PrimFun (a -> Int) -- PrimSignificand :: FloatingType a -> PrimFun (a -> a) -- PrimScaleFloat :: FloatingType a -> PrimFun ((Int, a) -> a)- -- PrimIsInfinite :: FloatingType a -> PrimFun (a -> Bool) -- PrimIsDenormalized :: FloatingType a -> PrimFun (a -> Bool) -- PrimIsNegativeZero :: FloatingType a -> PrimFun (a -> Bool) -- PrimIsIEEE :: FloatingType a -> PrimFun (a -> Bool)@@ -1175,8 +1126,8 @@ -- rnfS :: PreOpenSeq acc aenv' senv' t' -> () -- rnfS = rnfPreOpenSeq rnfA - rnfB :: forall aenv' sh e. Elt e => acc aenv' (Array sh e) -> Boundary (EltRepr e) -> ()- rnfB _ = rnfBoundary (eltType (undefined::e))+ rnfB :: PreBoundary acc aenv' (Array sh e) -> ()+ rnfB = rnfBoundary rnfA in case pacc of Alet bnd body -> rnfA bnd `seq` rnfA body@@ -1208,8 +1159,8 @@ Scanr' f z a -> rnfF f `seq` rnfE z `seq` rnfA a Permute f d p a -> rnfF f `seq` rnfA d `seq` rnfF p `seq` rnfA a Backpermute sh f a -> rnfE sh `seq` rnfF f `seq` rnfA a- Stencil f b a -> rnfF f `seq` rnfB a b `seq` rnfA a- Stencil2 f b1 a1 b2 a2 -> rnfF f `seq` rnfB a1 b1 `seq` rnfB a2 b2 `seq` rnfA a1 `seq` rnfA a2+ Stencil f b a -> rnfF f `seq` rnfB b `seq` rnfA a+ Stencil2 f b1 a1 b2 a2 -> rnfF f `seq` rnfB b1 `seq` rnfB b2 `seq` rnfA a1 `seq` rnfA a2 -- Collect s -> rnfS s @@ -1222,11 +1173,12 @@ rnfArrays ArraysRarray arr = rnf arr rnfArrays (ArraysRpair ar1 ar2) (a1,a2) = rnfArrays ar1 a1 `seq` rnfArrays ar2 a2 -rnfBoundary :: TupleType t -> Boundary t -> ()-rnfBoundary _ Clamp = ()-rnfBoundary _ Mirror = ()-rnfBoundary _ Wrap = ()-rnfBoundary t (Constant c) = rnfConst t c+rnfBoundary :: forall acc aenv sh e. NFDataAcc acc -> PreBoundary acc aenv (Array sh e) -> ()+rnfBoundary _ Clamp = ()+rnfBoundary _ Mirror = ()+rnfBoundary _ Wrap = ()+rnfBoundary _ (Constant c) = rnfConst (eltType (undefined::e)) c+rnfBoundary rnfA (Function f) = rnfPreOpenFun rnfA f {--@@ -1401,6 +1353,7 @@ rnfPrimFun (PrimFloor f i) = rnfFloatingType f `seq` rnfIntegralType i rnfPrimFun (PrimCeiling f i) = rnfFloatingType f `seq` rnfIntegralType i rnfPrimFun (PrimIsNaN t) = rnfFloatingType t+rnfPrimFun (PrimIsInfinite t) = rnfFloatingType t rnfPrimFun (PrimAtan2 t) = rnfFloatingType t rnfPrimFun (PrimLt t) = rnfScalarType t rnfPrimFun (PrimGt t) = rnfScalarType t@@ -1471,8 +1424,390 @@ rnfFloatingType (TypeCDouble FloatingDict) = () +-- Template Haskell+-- ================++type LiftAcc acc = forall aenv a. acc aenv a -> Q (TExp (acc aenv a))++liftIdx :: Idx env t -> Q (TExp (Idx env t))+liftIdx ZeroIdx = [|| ZeroIdx ||]+liftIdx (SuccIdx ix) = [|| SuccIdx $$(liftIdx ix) ||]++liftTupleIdx :: TupleIdx t e -> Q (TExp (TupleIdx t e))+liftTupleIdx ZeroTupIdx = [|| ZeroTupIdx ||]+liftTupleIdx (SuccTupIdx tix) = [|| SuccTupIdx $$(liftTupleIdx tix) ||]+++liftPreOpenAfun :: LiftAcc acc -> PreOpenAfun acc aenv t -> Q (TExp (PreOpenAfun acc aenv t))+liftPreOpenAfun liftA (Alam f) = [|| Alam $$(liftPreOpenAfun liftA f) ||]+liftPreOpenAfun liftA (Abody b) = [|| Abody $$(liftA b) ||]++liftPreOpenAcc+ :: forall acc aenv a.+ LiftAcc acc+ -> PreOpenAcc acc aenv a+ -> Q (TExp (PreOpenAcc acc aenv a))+liftPreOpenAcc liftA pacc =+ let+ liftE :: PreOpenExp acc env aenv t -> Q (TExp (PreOpenExp acc env aenv t))+ liftE = liftPreOpenExp liftA++ liftF :: PreOpenFun acc env aenv t -> Q (TExp (PreOpenFun acc env aenv t))+ liftF = liftPreOpenFun liftA++ liftAF :: PreOpenAfun acc aenv f -> Q (TExp (PreOpenAfun acc aenv f))+ liftAF = liftPreOpenAfun liftA++ liftB :: PreBoundary acc aenv (Array sh e) -> Q (TExp (PreBoundary acc aenv (Array sh e)))+ liftB = liftBoundary liftA++ liftAtuple :: Atuple (acc aenv) t -> Q (TExp (Atuple (acc aenv) t))+ liftAtuple NilAtup = [|| NilAtup ||]+ liftAtuple (SnocAtup tup a) = [|| SnocAtup $$(liftAtuple tup) $$(liftA a) ||]+ in+ case pacc of+ Alet bnd body -> [|| Alet $$(liftA bnd) $$(liftA body) ||]+ Avar ix -> [|| Avar $$(liftIdx ix) ||]+ Atuple tup -> [|| Atuple $$(liftAtuple tup) ||]+ Aprj tix a -> [|| Aprj $$(liftTupleIdx tix) $$(liftA a) ||]+ Apply f a -> [|| Apply $$(liftAF f) $$(liftA a) ||]+ Aforeign asm f a -> [|| Aforeign $$(liftForeign asm) $$(liftPreOpenAfun liftA f) $$(liftA a) ||]+ Acond p t e -> [|| Acond $$(liftE p) $$(liftA t) $$(liftA e) ||]+ Awhile p f a -> [|| Awhile $$(liftAF p) $$(liftAF f) $$(liftA a) ||]+ Use a -> [|| Use $$(liftArrays (arrays (undefined::a)) a) ||]+ Unit e -> [|| Unit $$(liftE e) ||]+ Reshape sh a -> [|| Reshape $$(liftE sh) $$(liftA a) ||]+ Generate sh f -> [|| Generate $$(liftE sh) $$(liftF f) ||]+ Transform sh p f a -> [|| Transform $$(liftE sh) $$(liftF p) $$(liftF f) $$(liftA a) ||]+ Replicate slix sl a -> [|| Replicate $$(liftSliceIndex slix) $$(liftE sl) $$(liftA a) ||]+ Slice slix a sh -> [|| Slice $$(liftSliceIndex slix) $$(liftA a) $$(liftE sh) ||]+ Map f a -> [|| Map $$(liftF f) $$(liftA a) ||]+ ZipWith f a b -> [|| ZipWith $$(liftF f) $$(liftA a) $$(liftA b) ||]+ Fold f z a -> [|| Fold $$(liftF f) $$(liftE z) $$(liftA a) ||]+ Fold1 f a -> [|| Fold1 $$(liftF f) $$(liftA a) ||]+ FoldSeg f z a s -> [|| FoldSeg $$(liftF f) $$(liftE z) $$(liftA a) $$(liftA s) ||]+ Fold1Seg f a s -> [|| Fold1Seg $$(liftF f) $$(liftA a) $$(liftA s) ||]+ Scanl f z a -> [|| Scanl $$(liftF f) $$(liftE z) $$(liftA a) ||]+ Scanl1 f a -> [|| Scanl1 $$(liftF f) $$(liftA a) ||]+ Scanl' f z a -> [|| Scanl' $$(liftF f) $$(liftE z) $$(liftA a) ||]+ Scanr f z a -> [|| Scanr $$(liftF f) $$(liftE z) $$(liftA a) ||]+ Scanr1 f a -> [|| Scanr1 $$(liftF f) $$(liftA a) ||]+ Scanr' f z a -> [|| Scanr' $$(liftF f) $$(liftE z) $$(liftA a) ||]+ Permute f d p a -> [|| Permute $$(liftF f) $$(liftA d) $$(liftF p) $$(liftA a) ||]+ Backpermute sh p a -> [|| Backpermute $$(liftE sh) $$(liftF p) $$(liftA a) ||]+ Stencil f b a -> [|| Stencil $$(liftF f) $$(liftB b) $$(liftA a) ||]+ Stencil2 f b1 a1 b2 a2 -> [|| Stencil2 $$(liftF f) $$(liftB b1) $$(liftA a1) $$(liftB b2) $$(liftA a2) ||]+++liftPreOpenFun+ :: LiftAcc acc+ -> PreOpenFun acc env aenv t+ -> Q (TExp (PreOpenFun acc env aenv t))+liftPreOpenFun liftA (Lam f) = [|| Lam $$(liftPreOpenFun liftA f) ||]+liftPreOpenFun liftA (Body b) = [|| Body $$(liftPreOpenExp liftA b) ||]++liftPreOpenExp+ :: forall acc env aenv t.+ LiftAcc acc+ -> PreOpenExp acc env aenv t+ -> Q (TExp (PreOpenExp acc env aenv t))+liftPreOpenExp liftA pexp =+ let+ liftE :: PreOpenExp acc env aenv e -> Q (TExp (PreOpenExp acc env aenv e))+ liftE = liftPreOpenExp liftA++ liftF :: PreOpenFun acc env aenv f -> Q (TExp (PreOpenFun acc env aenv f))+ liftF = liftPreOpenFun liftA++ liftT :: Tuple (PreOpenExp acc env aenv) e -> Q (TExp (Tuple (PreOpenExp acc env aenv) e))+ liftT NilTup = [|| NilTup ||]+ liftT (SnocTup tup e) = [|| SnocTup $$(liftT tup) $$(liftE e) ||]+ in+ case pexp of+ Let bnd body -> [|| Let $$(liftPreOpenExp liftA bnd) $$(liftPreOpenExp liftA body) ||]+ Var ix -> [|| Var $$(liftIdx ix) ||]+ Foreign asm f x -> [|| Foreign $$(liftForeign asm) $$(liftPreOpenFun liftA f) $$(liftE x) ||]+ Const c -> [|| Const $$(liftConst (eltType (undefined::t)) c) ||]+ Tuple tup -> [|| Tuple $$(liftT tup) ||]+ Prj tix e -> [|| Prj $$(liftTupleIdx tix) $$(liftE e) ||]+ IndexNil -> [|| IndexNil ||]+ IndexCons sh sz -> [|| IndexCons $$(liftE sh) $$(liftE sz) ||]+ IndexHead sh -> [|| IndexHead $$(liftE sh) ||]+ IndexTail sh -> [|| IndexTail $$(liftE sh) ||]+ IndexAny -> [|| IndexAny ||]+ IndexSlice slice slix sh -> [|| IndexSlice $$(liftSliceIndex slice) $$(liftE slix) $$(liftE sh) ||]+ IndexFull slice slix sl -> [|| IndexFull $$(liftSliceIndex slice) $$(liftE slix) $$(liftE sl) ||]+ ToIndex sh ix -> [|| ToIndex $$(liftE sh) $$(liftE ix) ||]+ FromIndex sh ix -> [|| FromIndex $$(liftE sh) $$(liftE ix) ||]+ Cond p t e -> [|| Cond $$(liftE p) $$(liftE t) $$(liftE e) ||]+ While p f x -> [|| While $$(liftF p) $$(liftF f) $$(liftE x) ||]+ PrimConst t -> [|| PrimConst $$(liftPrimConst t) ||]+ PrimApp f x -> [|| PrimApp $$(liftPrimFun f) $$(liftE x) ||]+ Index a ix -> [|| Index $$(liftA a) $$(liftE ix) ||]+ LinearIndex a ix -> [|| LinearIndex $$(liftA a) $$(liftE ix) ||]+ Shape a -> [|| Shape $$(liftA a) ||]+ ShapeSize ix -> [|| ShapeSize $$(liftE ix) ||]+ Intersect sh1 sh2 -> [|| Intersect $$(liftE sh1) $$(liftE sh2) ||]+ Union sh1 sh2 -> [|| Union $$(liftE sh1) $$(liftE sh2) ||]+++liftArrays :: ArraysR arr -> arr -> Q (TExp arr)+liftArrays ArraysRunit () = [|| () ||]+liftArrays ArraysRarray arr = [|| $$(liftArray arr) ||]+liftArrays (ArraysRpair r1 r2) (a1,a2) = [|| ($$(liftArrays r1 a1), $$(liftArrays r2 a2)) ||]++liftArray :: forall sh e. Array sh e -> Q (TExp (Array sh e))+liftArray (Array sh adata) =+ [|| Array $$(liftConst (eltType (undefined::sh)) sh) $$(go arrayElt adata) ||] `sigE` typeRepToType (typeOf (undefined::Array sh e))+ where+ sz :: Int+ sz = size sh++ sigE :: Q (TExp t) -> Q TH.Type -> Q (TExp t)+ sigE e t = TH.unsafeTExpCoerce $ TH.sigE (TH.unTypeQ e) t++ typeRepToType :: TypeRep -> Q TH.Type+ typeRepToType trep = do+ let (con, args) = splitTyConApp trep+ name = TH.Name (TH.OccName (tyConName con)) (TH.NameG TH.TcClsName (TH.PkgName (tyConPackage con)) (TH.ModName (tyConModule con)))+ --+ appsT x [] = x+ appsT x (y:xs) = appsT (TH.AppT x y) xs+ --+ resultArgs <- mapM typeRepToType args+ return (appsT (TH.ConT name) resultArgs)++ -- TODO: make sure that the resulting array is 16-byte aligned...+ arr :: forall a. (ArrayElt a, Storable a) => UniqueArray a -> Q (TExp (UniqueArray a))+ arr ua = do+ bytes <- TH.runIO $ peekArray (sizeOf (undefined::a) * sz) (castPtr (unsafeUniqueArrayPtr ua) :: Ptr Word8)+ [|| unsafePerformIO $ do+ fp <- newForeignPtr_ $$( TH.unsafeTExpCoerce [| Ptr $(TH.litE (TH.StringPrimL bytes)) |] )+ ua' <- newUniqueArray (castForeignPtr fp)+ return ua'+ ||]++ go :: ArrayEltR e' -> ArrayData e' -> Q (TExp (ArrayData e'))+ go ArrayEltRunit AD_Unit = [|| AD_Unit ||]+ go ArrayEltRint (AD_Int ua) = [|| AD_Int $$(arr ua) ||]+ go ArrayEltRint8 (AD_Int8 ua) = [|| AD_Int8 $$(arr ua) ||]+ go ArrayEltRint16 (AD_Int16 ua) = [|| AD_Int16 $$(arr ua) ||]+ go ArrayEltRint32 (AD_Int32 ua) = [|| AD_Int32 $$(arr ua) ||]+ go ArrayEltRint64 (AD_Int64 ua) = [|| AD_Int64 $$(arr ua) ||]+ go ArrayEltRword (AD_Word ua) = [|| AD_Word $$(arr ua) ||]+ go ArrayEltRword8 (AD_Word8 ua) = [|| AD_Word8 $$(arr ua) ||]+ go ArrayEltRword16 (AD_Word16 ua) = [|| AD_Word16 $$(arr ua) ||]+ go ArrayEltRword32 (AD_Word32 ua) = [|| AD_Word32 $$(arr ua) ||]+ go ArrayEltRword64 (AD_Word64 ua) = [|| AD_Word64 $$(arr ua) ||]+ go ArrayEltRcshort (AD_CShort ua) = [|| AD_CShort $$(arr ua) ||]+ go ArrayEltRcushort (AD_CUShort ua) = [|| AD_CUShort $$(arr ua) ||]+ go ArrayEltRcint (AD_CInt ua) = [|| AD_CInt $$(arr ua) ||]+ go ArrayEltRcuint (AD_CUInt ua) = [|| AD_CUInt $$(arr ua) ||]+ go ArrayEltRclong (AD_CLong ua) = [|| AD_CLong $$(arr ua) ||]+ go ArrayEltRculong (AD_CULong ua) = [|| AD_CULong $$(arr ua) ||]+ go ArrayEltRcllong (AD_CLLong ua) = [|| AD_CLLong $$(arr ua) ||]+ go ArrayEltRcullong (AD_CULLong ua) = [|| AD_CULLong $$(arr ua) ||]+ go ArrayEltRfloat (AD_Float ua) = [|| AD_Float $$(arr ua) ||]+ go ArrayEltRdouble (AD_Double ua) = [|| AD_Double $$(arr ua) ||]+ go ArrayEltRcfloat (AD_CFloat ua) = [|| AD_CFloat $$(arr ua) ||]+ go ArrayEltRcdouble (AD_CDouble ua) = [|| AD_CDouble $$(arr ua) ||]+ go ArrayEltRbool (AD_Bool ua) = [|| AD_Bool $$(arr ua) ||]+ go ArrayEltRchar (AD_Char ua) = [|| AD_Char $$(arr ua) ||]+ go ArrayEltRcchar (AD_CChar ua) = [|| AD_CChar $$(arr ua) ||]+ go ArrayEltRcschar (AD_CSChar ua) = [|| AD_CSChar $$(arr ua) ||]+ go ArrayEltRcuchar (AD_CUChar ua) = [|| AD_CUChar $$(arr ua) ||]+ go (ArrayEltRpair r1 r2) (AD_Pair a1 a2) = [|| AD_Pair $$(go r1 a1) $$(go r2 a2) ||]+++liftBoundary+ :: forall acc aenv sh e.+ LiftAcc acc+ -> PreBoundary acc aenv (Array sh e)+ -> Q (TExp (PreBoundary acc aenv (Array sh e)))+liftBoundary _ Clamp = [|| Clamp ||]+liftBoundary _ Mirror = [|| Mirror ||]+liftBoundary _ Wrap = [|| Wrap ||]+liftBoundary _ (Constant v) = [|| Constant $$(liftConst (eltType (undefined::e)) v) ||]+liftBoundary liftA (Function f) = [|| Function $$(liftPreOpenFun liftA f) ||]++liftSliceIndex :: SliceIndex ix slice coSlice sliceDim -> Q (TExp (SliceIndex ix slice coSlice sliceDim))+liftSliceIndex SliceNil = [|| SliceNil ||]+liftSliceIndex (SliceAll rest) = [|| SliceAll $$(liftSliceIndex rest) ||]+liftSliceIndex (SliceFixed rest) = [|| SliceFixed $$(liftSliceIndex rest) ||]++liftPrimConst :: PrimConst c -> Q (TExp (PrimConst c))+liftPrimConst (PrimMinBound t) = [|| PrimMinBound $$(liftBoundedType t) ||]+liftPrimConst (PrimMaxBound t) = [|| PrimMaxBound $$(liftBoundedType t) ||]+liftPrimConst (PrimPi t) = [|| PrimPi $$(liftFloatingType t) ||]++liftPrimFun :: PrimFun f -> Q (TExp (PrimFun f))+liftPrimFun (PrimAdd t) = [|| PrimAdd $$(liftNumType t) ||]+liftPrimFun (PrimSub t) = [|| PrimSub $$(liftNumType t) ||]+liftPrimFun (PrimMul t) = [|| PrimMul $$(liftNumType t) ||]+liftPrimFun (PrimNeg t) = [|| PrimNeg $$(liftNumType t) ||]+liftPrimFun (PrimAbs t) = [|| PrimAbs $$(liftNumType t) ||]+liftPrimFun (PrimSig t) = [|| PrimSig $$(liftNumType t) ||]+liftPrimFun (PrimQuot t) = [|| PrimQuot $$(liftIntegralType t) ||]+liftPrimFun (PrimRem t) = [|| PrimRem $$(liftIntegralType t) ||]+liftPrimFun (PrimQuotRem t) = [|| PrimQuotRem $$(liftIntegralType t) ||]+liftPrimFun (PrimIDiv t) = [|| PrimIDiv $$(liftIntegralType t) ||]+liftPrimFun (PrimMod t) = [|| PrimMod $$(liftIntegralType t) ||]+liftPrimFun (PrimDivMod t) = [|| PrimDivMod $$(liftIntegralType t) ||]+liftPrimFun (PrimBAnd t) = [|| PrimBAnd $$(liftIntegralType t) ||]+liftPrimFun (PrimBOr t) = [|| PrimBOr $$(liftIntegralType t) ||]+liftPrimFun (PrimBXor t) = [|| PrimBXor $$(liftIntegralType t) ||]+liftPrimFun (PrimBNot t) = [|| PrimBNot $$(liftIntegralType t) ||]+liftPrimFun (PrimBShiftL t) = [|| PrimBShiftL $$(liftIntegralType t) ||]+liftPrimFun (PrimBShiftR t) = [|| PrimBShiftR $$(liftIntegralType t) ||]+liftPrimFun (PrimBRotateL t) = [|| PrimBRotateL $$(liftIntegralType t) ||]+liftPrimFun (PrimBRotateR t) = [|| PrimBRotateR $$(liftIntegralType t) ||]+liftPrimFun (PrimPopCount t) = [|| PrimPopCount $$(liftIntegralType t) ||]+liftPrimFun (PrimCountLeadingZeros t) = [|| PrimCountLeadingZeros $$(liftIntegralType t) ||]+liftPrimFun (PrimCountTrailingZeros t) = [|| PrimCountTrailingZeros $$(liftIntegralType t) ||]+liftPrimFun (PrimFDiv t) = [|| PrimFDiv $$(liftFloatingType t) ||]+liftPrimFun (PrimRecip t) = [|| PrimRecip $$(liftFloatingType t) ||]+liftPrimFun (PrimSin t) = [|| PrimSin $$(liftFloatingType t) ||]+liftPrimFun (PrimCos t) = [|| PrimCos $$(liftFloatingType t) ||]+liftPrimFun (PrimTan t) = [|| PrimTan $$(liftFloatingType t) ||]+liftPrimFun (PrimAsin t) = [|| PrimAsin $$(liftFloatingType t) ||]+liftPrimFun (PrimAcos t) = [|| PrimAcos $$(liftFloatingType t) ||]+liftPrimFun (PrimAtan t) = [|| PrimAtan $$(liftFloatingType t) ||]+liftPrimFun (PrimSinh t) = [|| PrimSinh $$(liftFloatingType t) ||]+liftPrimFun (PrimCosh t) = [|| PrimCosh $$(liftFloatingType t) ||]+liftPrimFun (PrimTanh t) = [|| PrimTanh $$(liftFloatingType t) ||]+liftPrimFun (PrimAsinh t) = [|| PrimAsinh $$(liftFloatingType t) ||]+liftPrimFun (PrimAcosh t) = [|| PrimAcosh $$(liftFloatingType t) ||]+liftPrimFun (PrimAtanh t) = [|| PrimAtanh $$(liftFloatingType t) ||]+liftPrimFun (PrimExpFloating t) = [|| PrimExpFloating $$(liftFloatingType t) ||]+liftPrimFun (PrimSqrt t) = [|| PrimSqrt $$(liftFloatingType t) ||]+liftPrimFun (PrimLog t) = [|| PrimLog $$(liftFloatingType t) ||]+liftPrimFun (PrimFPow t) = [|| PrimFPow $$(liftFloatingType t) ||]+liftPrimFun (PrimLogBase t) = [|| PrimLogBase $$(liftFloatingType t) ||]+liftPrimFun (PrimTruncate ta tb) = [|| PrimTruncate $$(liftFloatingType ta) $$(liftIntegralType tb) ||]+liftPrimFun (PrimRound ta tb) = [|| PrimRound $$(liftFloatingType ta) $$(liftIntegralType tb) ||]+liftPrimFun (PrimFloor ta tb) = [|| PrimFloor $$(liftFloatingType ta) $$(liftIntegralType tb) ||]+liftPrimFun (PrimCeiling ta tb) = [|| PrimCeiling $$(liftFloatingType ta) $$(liftIntegralType tb) ||]+liftPrimFun (PrimIsNaN t) = [|| PrimIsNaN $$(liftFloatingType t) ||]+liftPrimFun (PrimIsInfinite t) = [|| PrimIsInfinite $$(liftFloatingType t) ||]+liftPrimFun (PrimAtan2 t) = [|| PrimAtan2 $$(liftFloatingType t) ||]+liftPrimFun (PrimLt t) = [|| PrimLt $$(liftScalarType t) ||]+liftPrimFun (PrimGt t) = [|| PrimGt $$(liftScalarType t) ||]+liftPrimFun (PrimLtEq t) = [|| PrimLtEq $$(liftScalarType t) ||]+liftPrimFun (PrimGtEq t) = [|| PrimGtEq $$(liftScalarType t) ||]+liftPrimFun (PrimEq t) = [|| PrimEq $$(liftScalarType t) ||]+liftPrimFun (PrimNEq t) = [|| PrimNEq $$(liftScalarType t) ||]+liftPrimFun (PrimMax t) = [|| PrimMax $$(liftScalarType t) ||]+liftPrimFun (PrimMin t) = [|| PrimMin $$(liftScalarType t) ||]+liftPrimFun PrimLAnd = [|| PrimLAnd ||]+liftPrimFun PrimLOr = [|| PrimLOr ||]+liftPrimFun PrimLNot = [|| PrimLNot ||]+liftPrimFun PrimOrd = [|| PrimOrd ||]+liftPrimFun PrimChr = [|| PrimChr ||]+liftPrimFun PrimBoolToInt = [|| PrimBoolToInt ||]+liftPrimFun (PrimFromIntegral ta tb) = [|| PrimFromIntegral $$(liftIntegralType ta) $$(liftNumType tb) ||]+liftPrimFun (PrimToFloating ta tb) = [|| PrimToFloating $$(liftNumType ta) $$(liftFloatingType tb) ||]+liftPrimFun (PrimCoerce ta tb) = [|| PrimCoerce $$(liftScalarType ta) $$(liftScalarType tb) ||]+++liftConst :: TupleType t -> t -> Q (TExp t)+liftConst UnitTuple () = [|| () ||]+liftConst (SingleTuple t) x = [|| $$(liftScalar t x) ||]+liftConst (PairTuple ta tb) (a,b) = [|| ($$(liftConst ta a), $$(liftConst tb b)) ||]++liftScalar :: ScalarType t -> t -> Q (TExp t)+liftScalar (NumScalarType t) x = liftNum t x+liftScalar (NonNumScalarType t) x = liftNonNum t x++liftNum :: NumType t -> t -> Q (TExp t)+liftNum (IntegralNumType t) x = liftIntegral t x+liftNum (FloatingNumType t) x = liftFloating t x++liftNonNum :: NonNumType t -> t -> Q (TExp t)+liftNonNum TypeBool{} x = [|| x ||]+liftNonNum TypeChar{} x = [|| x ||]+liftNonNum TypeCChar{} x = return (TH.TExp (TH.LitE (TH.IntegerL (toInteger x))))+liftNonNum TypeCSChar{} x = return (TH.TExp (TH.LitE (TH.IntegerL (toInteger x))))+liftNonNum TypeCUChar{} x = return (TH.TExp (TH.LitE (TH.IntegerL (toInteger x))))++liftIntegral :: IntegralType t -> t -> Q (TExp t)+liftIntegral TypeInt{} x = [|| x ||]+liftIntegral TypeInt8{} x = [|| x ||]+liftIntegral TypeInt16{} x = [|| x ||]+liftIntegral TypeInt32{} x = [|| x ||]+liftIntegral TypeInt64{} x = [|| x ||]+#if __GLASGOW_HASKELL__ >= 710+liftIntegral TypeWord{} x = [|| x ||]+#else+liftIntegral TypeWord{} x = return (TH.TExp (TH.LitE (TH.IntegerL (toInteger x))))+#endif+liftIntegral TypeWord8{} x = [|| x ||]+liftIntegral TypeWord16{} x = [|| x ||]+liftIntegral TypeWord32{} x = [|| x ||]+liftIntegral TypeWord64{} x = [|| x ||]+liftIntegral TypeCShort{} x = return (TH.TExp (TH.LitE (TH.IntegerL (toInteger x))))+liftIntegral TypeCUShort{} x = return (TH.TExp (TH.LitE (TH.IntegerL (toInteger x))))+liftIntegral TypeCInt{} x = return (TH.TExp (TH.LitE (TH.IntegerL (toInteger x))))+liftIntegral TypeCUInt{} x = return (TH.TExp (TH.LitE (TH.IntegerL (toInteger x))))+liftIntegral TypeCLong{} x = return (TH.TExp (TH.LitE (TH.IntegerL (toInteger x))))+liftIntegral TypeCULong{} x = return (TH.TExp (TH.LitE (TH.IntegerL (toInteger x))))+liftIntegral TypeCLLong{} x = return (TH.TExp (TH.LitE (TH.IntegerL (toInteger x))))+liftIntegral TypeCULLong{} x = return (TH.TExp (TH.LitE (TH.IntegerL (toInteger x))))++liftFloating :: FloatingType t -> t -> Q (TExp t)+liftFloating TypeFloat{} x = [|| x ||]+liftFloating TypeDouble{} x = [|| x ||]+liftFloating TypeCFloat{} x = return (TH.TExp (TH.LitE (TH.RationalL (toRational x))))+liftFloating TypeCDouble{} x = return (TH.TExp (TH.LitE (TH.RationalL (toRational x))))+++liftIntegralType :: IntegralType t -> Q (TExp (IntegralType t))+liftIntegralType TypeInt{} = [|| TypeInt IntegralDict ||]+liftIntegralType TypeInt8{} = [|| TypeInt8 IntegralDict ||]+liftIntegralType TypeInt16{} = [|| TypeInt16 IntegralDict ||]+liftIntegralType TypeInt32{} = [|| TypeInt32 IntegralDict ||]+liftIntegralType TypeInt64{} = [|| TypeInt64 IntegralDict ||]+liftIntegralType TypeWord{} = [|| TypeWord IntegralDict ||]+liftIntegralType TypeWord8{} = [|| TypeWord8 IntegralDict ||]+liftIntegralType TypeWord16{} = [|| TypeWord16 IntegralDict ||]+liftIntegralType TypeWord32{} = [|| TypeWord32 IntegralDict ||]+liftIntegralType TypeWord64{} = [|| TypeWord64 IntegralDict ||]+liftIntegralType TypeCShort{} = [|| TypeCShort IntegralDict ||]+liftIntegralType TypeCUShort{} = [|| TypeCUShort IntegralDict ||]+liftIntegralType TypeCInt{} = [|| TypeCInt IntegralDict ||]+liftIntegralType TypeCUInt{} = [|| TypeCUInt IntegralDict ||]+liftIntegralType TypeCLong{} = [|| TypeCLong IntegralDict ||]+liftIntegralType TypeCULong{} = [|| TypeCULong IntegralDict ||]+liftIntegralType TypeCLLong{} = [|| TypeCLLong IntegralDict ||]+liftIntegralType TypeCULLong{} = [|| TypeCULLong IntegralDict ||]++liftFloatingType :: FloatingType t -> Q (TExp (FloatingType t))+liftFloatingType TypeFloat{} = [|| TypeFloat FloatingDict ||]+liftFloatingType TypeDouble{} = [|| TypeDouble FloatingDict ||]+liftFloatingType TypeCFloat{} = [|| TypeCFloat FloatingDict ||]+liftFloatingType TypeCDouble{} = [|| TypeCDouble FloatingDict ||]++liftNonNumType :: NonNumType t -> Q (TExp (NonNumType t))+liftNonNumType TypeBool{} = [|| TypeBool NonNumDict ||]+liftNonNumType TypeChar{} = [|| TypeChar NonNumDict ||]+liftNonNumType TypeCChar{} = [|| TypeCChar NonNumDict ||]+liftNonNumType TypeCSChar{} = [|| TypeCSChar NonNumDict ||]+liftNonNumType TypeCUChar{} = [|| TypeCUChar NonNumDict ||]++liftNumType :: NumType t -> Q (TExp (NumType t))+liftNumType (IntegralNumType t) = [|| IntegralNumType $$(liftIntegralType t) ||]+liftNumType (FloatingNumType t) = [|| FloatingNumType $$(liftFloatingType t) ||]++liftBoundedType :: BoundedType t -> Q (TExp (BoundedType t))+liftBoundedType (IntegralBoundedType t) = [|| IntegralBoundedType $$(liftIntegralType t) ||]+liftBoundedType (NonNumBoundedType t) = [|| NonNumBoundedType $$(liftNonNumType t) ||]++liftScalarType :: ScalarType t -> Q (TExp (ScalarType t))+liftScalarType (NumScalarType t) = [|| NumScalarType $$(liftNumType t) ||]+liftScalarType (NonNumScalarType t) = [|| NonNumScalarType $$(liftNonNumType t) ||]++ -- Debugging--- ---------+-- ========= showPreAccOp :: forall acc aenv arrs. PreOpenAcc acc aenv arrs -> String showPreAccOp Alet{} = "Alet"@@ -1525,7 +1860,7 @@ showShortendArr arr = show (take cutoff l) ++ if length l > cutoff then ".." else "" where- l = Sugar.toList arr+ l = toList arr cutoff = 5
+ Data/Array/Accelerate/Analysis/Hash.hs view
@@ -0,0 +1,506 @@+{-# LANGUAGE GADTs #-}+{-# LANGUAGE PatternGuards #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# OPTIONS_HADDOCK hide #-}+-- |+-- Module : Data.Array.Accelerate.Analysis.Hash+-- Copyright : [2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--++module Data.Array.Accelerate.Analysis.Hash (++ -- hashing expressions+ HashAcc,+ hashPreOpenAcc, hashOpenAcc,+ hashPreOpenExp, hashOpenExp,+ hashPreOpenFun,++ -- auxiliary+ hashQ,+ commutes,++) where++import Data.Array.Accelerate.AST+import Data.Array.Accelerate.Analysis.Hash.TH+import Data.Array.Accelerate.Array.Sugar+import Data.Array.Accelerate.Array.Representation ( SliceIndex(..) )+import Data.Array.Accelerate.Product+import Data.Array.Accelerate.Type++import Data.Hashable+import Foreign.C.Types+import Data.Maybe ( fromMaybe )+import System.Mem.StableName ( hashStableName, makeStableName )+import System.IO.Unsafe ( unsafePerformIO )+import Prelude hiding ( exp )+++-- Array computations+-- ------------------++type HashAcc acc = forall aenv a. acc aenv a -> Int+++hashOpenAcc :: OpenAcc aenv arrs -> Int+hashOpenAcc (OpenAcc pacc) = hashPreOpenAcc hashOpenAcc pacc++hashPreOpenAcc :: forall acc aenv arrs. HashAcc acc -> PreOpenAcc acc aenv arrs -> Int+hashPreOpenAcc hashAcc pacc =+ let+ hashA :: forall aenv' a. Arrays a => Int -> acc aenv' a -> Int+ hashA salt+ = hashWithSalt salt+ . hashWithSalt (hashArraysType (arrays (undefined::a)))+ . hashAcc++ hashE :: Int -> PreOpenExp acc env' aenv' e -> Int+ hashE salt = hashWithSalt salt . hashPreOpenExp hashAcc++ hashF :: Int -> PreOpenFun acc env' aenv' f -> Int+ hashF salt = hashWithSalt salt . hashPreOpenFun hashAcc++ hashB :: Int -> PreBoundary acc aenv' (Array sh e) -> Int+ hashB salt = hashWithSalt salt . hashPreBoundary hashAcc++ -- hashS :: Int -> PreOpenSeq acc aenv senv arrs -> Int+ -- hashS salt = hashWithSalt salt . hashPreOpenSeq hashAcc++ nacl :: Arrays arrs => Int+ nacl = hashArraysType (arrays (undefined::arrs))++ in case pacc of+ Alet bnd body -> $(hashQ "Alet") `hashA` bnd `hashA` body+ Avar v -> $(hashQ "Avar") `hashWithSalt` nacl `hashWithSalt` hashIdx v+ Atuple t -> $(hashQ "Atuple") `hashWithSalt` nacl `hashWithSalt` hashAtuple hashAcc t+ Aprj ix a -> $(hashQ "Aprj") `hashWithSalt` nacl `hashWithSalt` hashTupleIdx ix `hashA` a+ Apply f a -> $(hashQ "Apply") `hashWithSalt` nacl `hashWithSalt` hashAfun hashAcc f `hashA` a+ Aforeign _ f a -> $(hashQ "Aforeign") `hashWithSalt` nacl `hashWithSalt` hashAfun hashAcc f `hashA` a+ Use a -> $(hashQ "Use") `hashWithSalt` hashArrays (arrays (undefined::arrs)) a+ Awhile p f a -> $(hashQ "Awhile") `hashWithSalt` hashAfun hashAcc f `hashWithSalt` hashAfun hashAcc p `hashA` a+ Unit e -> $(hashQ "Unit") `hashE` e+ Generate e f -> $(hashQ "Generate") `hashE` e `hashF` f+ Acond e a1 a2 -> $(hashQ "Acond") `hashE` e `hashA` a1 `hashA` a2+ Reshape sh a -> $(hashQ "Reshape") `hashE` sh `hashA` a+ Transform sh f1 f2 a -> $(hashQ "Transform") `hashE` sh `hashF` f1 `hashF` f2 `hashA` a+ Replicate spec ix a -> $(hashQ "Replicate") `hashE` ix `hashA` a `hashWithSalt` hashSliceIndex spec+ Slice spec a ix -> $(hashQ "Slice") `hashE` ix `hashA` a `hashWithSalt` hashSliceIndex spec+ Map f a -> $(hashQ "Map") `hashF` f `hashA` a+ ZipWith f a1 a2 -> $(hashQ "ZipWith") `hashF` f `hashA` a1 `hashA` a2+ Fold f e a -> $(hashQ "Fold") `hashF` f `hashE` e `hashA` a+ Fold1 f a -> $(hashQ "Fold1") `hashF` f `hashA` a+ FoldSeg f e a s -> $(hashQ "FoldSeg") `hashF` f `hashE` e `hashA` a `hashA` s+ Fold1Seg f a s -> $(hashQ "Fold1Seg") `hashF` f `hashA` a `hashA` s+ Scanl f e a -> $(hashQ "Scanl") `hashF` f `hashE` e `hashA` a+ Scanl' f e a -> $(hashQ "Scanl'") `hashF` f `hashE` e `hashA` a+ Scanl1 f a -> $(hashQ "Scanl1") `hashF` f `hashA` a+ Scanr f e a -> $(hashQ "Scanr") `hashF` f `hashE` e `hashA` a+ Scanr' f e a -> $(hashQ "Scanr'") `hashF` f `hashE` e `hashA` a+ Scanr1 f a -> $(hashQ "Scanr1") `hashF` f `hashA` a+ Backpermute sh f a -> $(hashQ "Backpermute") `hashF` f `hashE` sh `hashA` a+ Permute f1 a1 f2 a2 -> $(hashQ "Permute") `hashF` f1 `hashA` a1 `hashF` f2 `hashA` a2+ Stencil f b a -> $(hashQ "Stencil") `hashF` f `hashB` b `hashA` a+ Stencil2 f b1 a1 b2 a2 -> $(hashQ "Stencil2") `hashF` f `hashB` b1 `hashA` a1 `hashB` b2 `hashA` a2++{--+hashPreOpenSeq :: forall acc aenv senv arrs. HashAcc acc -> PreOpenSeq acc aenv senv arrs -> Int+hashPreOpenSeq hashAcc s =+ let+ hashA :: Int -> acc aenv' a -> Int+ hashA salt = hashWithSalt salt . hashAcc++ hashE :: Int -> PreOpenExp acc env' aenv' e -> Int+ hashE salt = hashWithSalt salt . hashPreOpenExp hashAcc++ hashAF :: Int -> PreOpenAfun acc aenv' f -> Int+ hashAF salt = hashWithSalt salt . hashAfun hashAcc++ hashF :: Int -> PreOpenFun acc env' aenv' f -> Int+ hashF salt = hashWithSalt salt . hashPreOpenFun hashAcc++ hashS :: Int -> PreOpenSeq acc aenv senv' arrs' -> Int+ hashS salt = hashWithSalt salt . hashPreOpenSeq hashAcc++ hashVar :: Int -> Idx senv' a -> Int+ hashVar salt = hashWithSalt salt . idxToInt++ hashP :: Int -> Producer acc aenv senv a -> Int+ hashP salt p =+ case p of+ StreamIn arrs -> unsafePerformIO $! hashStableName `fmap` makeStableName arrs+ ToSeq spec _ acc -> hashWithSalt salt "ToSeq" `hashA` acc `hashWithSalt` show spec+ MapSeq f x -> hashWithSalt salt "MapSeq" `hashAF` f `hashVar` x+ ChunkedMapSeq f x -> hashWithSalt salt "ChunkedMapSeq" `hashAF` f `hashVar` x+ ZipWithSeq f x y -> hashWithSalt salt "ZipWithSeq" `hashAF` f `hashVar` x `hashVar` y+ ScanSeq f e x -> hashWithSalt salt "ScanSeq" `hashF` f `hashE` e `hashVar` x++ hashC :: Int -> Consumer acc aenv senv' a -> Int+ hashC salt c =+ case c of+ FoldSeq f e x -> hashWithSalt salt "FoldSeq" `hashF` f `hashE` e `hashVar` x+ FoldSeqFlatten f acc x -> hashWithSalt salt "FoldSeqFlatten" `hashAF` f `hashA` acc `hashVar` x+ Stuple t -> hash "Stuple" `hashWithSalt` hashAtuple (hashC salt) t++ in case s of+ Producer p s' -> hash "Producer" `hashP` p `hashS` s'+ Consumer c -> hash "Consumer" `hashC` c+ Reify ix -> hash "Reify" `hashVar` ix+--}+++hashIdx :: Idx env t -> Int+hashIdx = hash . idxToInt++hashTupleIdx :: TupleIdx tup e -> Int+hashTupleIdx = hash . tupleIdxToInt+++hashArrays :: ArraysR a -> a -> Int+hashArrays ArraysRunit () = hash ()+hashArrays (ArraysRpair r1 r2) (a1, a2) = hash (hashArrays r1 a1, hashArrays r2 a2)+hashArrays ArraysRarray ad = unsafePerformIO $! hashStableName `fmap` makeStableName ad++hashArraysType :: forall a. ArraysR a -> Int+hashArraysType ArraysRunit = $(hashQ "ArraysRunit")+hashArraysType (ArraysRpair r1 r2) = $(hashQ "ArraysRpair") `hashWithSalt` hashArraysType r1 `hashWithSalt` hashArraysType r2+hashArraysType ArraysRarray = $(hashQ "ArraysRarray") `hashWithSalt` hashArrayType (undefined::a)+ where+ hashArrayType :: forall sh e. (Shape sh, Elt e) => Array sh e -> Int+ hashArrayType _ = hashTupleType (eltType (undefined::sh)) `hashWithSalt` hashTupleType (eltType (undefined::e))++hashAtuple :: HashAcc acc -> Atuple (acc aenv) a -> Int+hashAtuple _ NilAtup = $(hashQ "NilAtup")+hashAtuple h (SnocAtup t a) = $(hashQ "SnocAtup") `hashWithSalt` hashAtuple h t `hashWithSalt` h a++hashAfun :: forall acc aenv f. HashAcc acc -> PreOpenAfun acc aenv f -> Int+hashAfun hashAcc afun =+ let+ hashA :: forall aenv' a. Arrays a => Int -> acc aenv' a -> Int+ hashA salt+ = hashWithSalt salt+ . hashWithSalt (hashArraysType (arrays (undefined::a)))+ . hashAcc++ hashL :: forall aenv' a b. Arrays a => Int -> PreOpenAfun acc (aenv',a) b -> Int+ hashL salt+ = hashWithSalt salt+ . hashWithSalt (hashArraysType (arrays (undefined::a)))+ . hashAfun hashAcc++ in case afun of+ Abody b -> $(hashQ "Abody") `hashA` b+ Alam l -> $(hashQ "Alam") `hashL` l+++hashPreBoundary :: forall acc aenv sh e. HashAcc acc -> PreBoundary acc aenv (Array sh e) -> Int+hashPreBoundary _ Wrap = $(hashQ "Wrap")+hashPreBoundary _ Clamp = $(hashQ "Clamp")+hashPreBoundary _ Mirror = $(hashQ "Mirror")+hashPreBoundary _ (Constant c) = $(hashQ "Constant") `hashWithSalt` hashConst (eltType (undefined::e)) c+hashPreBoundary h (Function f) = $(hashQ "Function") `hashWithSalt` hashPreOpenFun h f++hashSliceIndex :: SliceIndex slix sl co sh -> Int+hashSliceIndex SliceNil = $(hashQ "SliceNil")+hashSliceIndex (SliceAll r) = $(hashQ "SliceAll") `hashWithSalt` hashSliceIndex r+hashSliceIndex (SliceFixed r) = $(hashQ "sliceFixed") `hashWithSalt` hashSliceIndex r+++-- Scalar expressions+-- ------------------++hashOpenExp :: OpenExp env aenv exp -> Int+hashOpenExp = hashPreOpenExp hashOpenAcc++hashPreOpenExp :: forall acc env aenv exp. HashAcc acc -> PreOpenExp acc env aenv exp -> Int+hashPreOpenExp hashAcc exp =+ let+ hashE :: forall env' aenv' e. Elt e => Int -> PreOpenExp acc env' aenv' e -> Int+ hashE salt+ = hashWithSalt salt+ . hashWithSalt (hashTupleType (eltType (undefined::e)))+ . hashPreOpenExp hashAcc++ hashA :: Int -> acc aenv' a -> Int+ hashA salt = hashWithSalt salt . hashAcc++ hashF :: Int -> PreOpenFun acc env' aenv' f -> Int+ hashF salt = hashWithSalt salt . hashPreOpenFun hashAcc++ nacl :: Elt exp => Int+ nacl = hashTupleType (eltType (undefined::exp))++ in case exp of+ Let bnd body -> $(hashQ "Let") `hashE` bnd `hashE` body+ Const c -> $(hashQ "Const") `hashWithSalt` hashConst (eltType (undefined::exp)) c+ Var ix -> $(hashQ "Var") `hashWithSalt` nacl `hashWithSalt` hashIdx ix+ Tuple t -> $(hashQ "Tuple") `hashWithSalt` nacl `hashWithSalt` hashTuple hashAcc t+ Prj i e -> $(hashQ "Prj") `hashWithSalt` nacl `hashWithSalt` hashTupleIdx i `hashE` e+ IndexAny -> $(hashQ "IndexAny") `hashWithSalt` nacl+ IndexNil -> $(hashQ "IndexNil")+ IndexCons sl a -> $(hashQ "IndexCons") `hashE` sl `hashE` a+ IndexHead sl -> $(hashQ "IndexHead") `hashE` sl+ IndexTail sl -> $(hashQ "IndexTail") `hashE` sl+ IndexSlice spec ix sh -> $(hashQ "IndexSlice") `hashE` ix `hashE` sh `hashWithSalt` hashSliceIndex spec+ IndexFull spec ix sl -> $(hashQ "IndexFull") `hashE` ix `hashE` sl `hashWithSalt` hashSliceIndex spec+ ToIndex sh i -> $(hashQ "ToIndex") `hashE` sh `hashE` i+ FromIndex sh i -> $(hashQ "FromIndex") `hashE` sh `hashE` i+ Cond c t e -> $(hashQ "Cond") `hashE` c `hashE` t `hashE` e+ While p f x -> $(hashQ "While") `hashF` p `hashF` f `hashE` x+ PrimApp f x -> $(hashQ "PrimApp") `hashWithSalt` hashPrimFun f `hashE` fromMaybe x (commutes hashAcc f x)+ PrimConst c -> $(hashQ "PrimConst") `hashWithSalt` hashPrimConst c+ Index a ix -> $(hashQ "Index") `hashA` a `hashE` ix+ LinearIndex a ix -> $(hashQ "LinearIndex") `hashA` a `hashE` ix+ Shape a -> $(hashQ "Shape") `hashA` a+ ShapeSize sh -> $(hashQ "ShapeSize") `hashE` sh+ Intersect sa sb -> $(hashQ "Intersect") `hashE` sa `hashE` sb+ Union sa sb -> $(hashQ "Union") `hashE` sa `hashE` sb+ Foreign _ f e -> $(hashQ "Foreign") `hashF` f `hashE` e+++hashPreOpenFun :: forall acc env aenv f. HashAcc acc -> PreOpenFun acc env aenv f -> Int+hashPreOpenFun hashAcc fun =+ let+ hashE :: forall env' aenv' e. Elt e => Int -> PreOpenExp acc env' aenv' e -> Int+ hashE salt+ = hashWithSalt salt+ . hashWithSalt (hashTupleType (eltType (undefined::e)))+ . hashPreOpenExp hashAcc++ hashL :: forall env' aenv' a b. Elt a => Int -> PreOpenFun acc (env',a) aenv' b -> Int+ hashL salt+ = hashWithSalt salt+ . hashWithSalt (hashTupleType (eltType (undefined::a)))+ . hashPreOpenFun hashAcc++ in case fun of+ Body b -> $(hashQ "Body") `hashE` b+ Lam f -> $(hashQ "Lam") `hashL` f+++hashTuple :: HashAcc acc -> Tuple (PreOpenExp acc env aenv) e -> Int+hashTuple _ NilTup = $(hashQ "NilTup")+hashTuple h (SnocTup t e) = $(hashQ "SnocTup") `hashWithSalt` hashTuple h t `hashWithSalt` hashPreOpenExp h e+++hashConst :: TupleType t -> t -> Int+hashConst UnitTuple () = hash ()+hashConst (PairTuple ta tb) (a,b) = hash (hashConst ta a, hashConst tb b)+hashConst (SingleTuple t) c = hashScalarConst t c++hashScalarConst :: ScalarType t -> t -> Int+hashScalarConst (NumScalarType t) = hashNumConst t+hashScalarConst (NonNumScalarType t) = hashNonNumConst t++hashNonNumConst :: NonNumType t -> t -> Int+hashNonNumConst TypeBool{} x = $(hashQ "Bool") `hashWithSalt` x+hashNonNumConst TypeChar{} x = $(hashQ "Char") `hashWithSalt` x+hashNonNumConst TypeCChar{} (CChar x) = $(hashQ "CChar") `hashWithSalt` x+hashNonNumConst TypeCSChar{} (CSChar x) = $(hashQ "CSChar") `hashWithSalt` x+hashNonNumConst TypeCUChar{} (CUChar x) = $(hashQ "CUChar") `hashWithSalt` x++hashNumConst :: NumType t -> t -> Int+hashNumConst (IntegralNumType t) = hashIntegralConst t+hashNumConst (FloatingNumType t) = hashFloatingConst t++hashIntegralConst :: IntegralType t -> t -> Int+hashIntegralConst TypeInt{} x = $(hashQ "Int") `hashWithSalt` x+hashIntegralConst TypeInt8{} x = $(hashQ "Int8") `hashWithSalt` x+hashIntegralConst TypeInt16{} x = $(hashQ "Int16") `hashWithSalt` x+hashIntegralConst TypeInt32{} x = $(hashQ "Int32") `hashWithSalt` x+hashIntegralConst TypeInt64{} x = $(hashQ "Int64") `hashWithSalt` x+hashIntegralConst TypeWord{} x = $(hashQ "Word") `hashWithSalt` x+hashIntegralConst TypeWord8{} x = $(hashQ "Word8") `hashWithSalt` x+hashIntegralConst TypeWord16{} x = $(hashQ "Word16") `hashWithSalt` x+hashIntegralConst TypeWord32{} x = $(hashQ "Word32") `hashWithSalt` x+hashIntegralConst TypeWord64{} x = $(hashQ "Word64") `hashWithSalt` x+hashIntegralConst TypeCShort{} (CShort x) = $(hashQ "CShort") `hashWithSalt` x+hashIntegralConst TypeCUShort{} (CUShort x) = $(hashQ "CUShort") `hashWithSalt` x+hashIntegralConst TypeCInt{} (CInt x) = $(hashQ "CInt") `hashWithSalt` x+hashIntegralConst TypeCUInt{} (CUInt x) = $(hashQ "CUInt") `hashWithSalt` x+hashIntegralConst TypeCLong{} (CLong x) = $(hashQ "CLong") `hashWithSalt` x+hashIntegralConst TypeCULong{} (CULong x) = $(hashQ "CULong") `hashWithSalt` x+hashIntegralConst TypeCLLong{} (CLLong x) = $(hashQ "CLLong") `hashWithSalt` x+hashIntegralConst TypeCULLong{} (CULLong x) = $(hashQ "CULLong") `hashWithSalt` x++hashFloatingConst :: FloatingType t -> t -> Int+hashFloatingConst TypeFloat{} x = $(hashQ "Float") `hashWithSalt` x+hashFloatingConst TypeDouble{} x = $(hashQ "Double") `hashWithSalt` x+hashFloatingConst TypeCFloat{} (CFloat x) = $(hashQ "CFloat") `hashWithSalt` x+hashFloatingConst TypeCDouble{} (CDouble x) = $(hashQ "CDouble") `hashWithSalt` x++hashPrimConst :: PrimConst c -> Int+hashPrimConst (PrimMinBound t) = $(hashQ "PrimMinBound") `hashWithSalt` hashBoundedType t+hashPrimConst (PrimMaxBound t) = $(hashQ "PrimMaxBound") `hashWithSalt` hashBoundedType t+hashPrimConst (PrimPi t) = $(hashQ "PrimPi") `hashWithSalt` hashFloatingType t+++hashPrimFun :: PrimFun f -> Int+hashPrimFun (PrimAdd a) = $(hashQ "PrimAdd") `hashWithSalt` hashNumType a+hashPrimFun (PrimSub a) = $(hashQ "PrimSub") `hashWithSalt` hashNumType a+hashPrimFun (PrimMul a) = $(hashQ "PrimMul") `hashWithSalt` hashNumType a+hashPrimFun (PrimNeg a) = $(hashQ "PrimNeg") `hashWithSalt` hashNumType a+hashPrimFun (PrimAbs a) = $(hashQ "PrimAbs") `hashWithSalt` hashNumType a+hashPrimFun (PrimSig a) = $(hashQ "PrimSig") `hashWithSalt` hashNumType a+hashPrimFun (PrimQuot a) = $(hashQ "PrimQuot") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimRem a) = $(hashQ "PrimRem") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimQuotRem a) = $(hashQ "PrimQuotRem") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimIDiv a) = $(hashQ "PrimIDiv") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimMod a) = $(hashQ "PrimMod") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimDivMod a) = $(hashQ "PrimDivMod") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimBAnd a) = $(hashQ "PrimBAnd") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimBOr a) = $(hashQ "PrimBOr") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimBXor a) = $(hashQ "PrimBXor") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimBNot a) = $(hashQ "PrimBNot") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimBShiftL a) = $(hashQ "PrimBShiftL") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimBShiftR a) = $(hashQ "PrimBShiftR") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimBRotateL a) = $(hashQ "PrimBRotateL") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimBRotateR a) = $(hashQ "PrimBRotateR") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimPopCount a) = $(hashQ "PrimPopCount") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimCountLeadingZeros a) = $(hashQ "PrimCountLeadingZeros") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimCountTrailingZeros a) = $(hashQ "PrimCountTrailingZeros") `hashWithSalt` hashIntegralType a+hashPrimFun (PrimFDiv a) = $(hashQ "PrimFDiv") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimRecip a) = $(hashQ "PrimRecip") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimSin a) = $(hashQ "PrimSin") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimCos a) = $(hashQ "PrimCos") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimTan a) = $(hashQ "PrimTan") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimAsin a) = $(hashQ "PrimAsin") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimAcos a) = $(hashQ "PrimAcos") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimAtan a) = $(hashQ "PrimAtan") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimSinh a) = $(hashQ "PrimSinh") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimCosh a) = $(hashQ "PrimCosh") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimTanh a) = $(hashQ "PrimTanh") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimAsinh a) = $(hashQ "PrimAsinh") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimAcosh a) = $(hashQ "PrimAcosh") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimAtanh a) = $(hashQ "PrimAtanh") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimExpFloating a) = $(hashQ "PrimExpFloating") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimSqrt a) = $(hashQ "PrimSqrt") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimLog a) = $(hashQ "PrimLog") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimFPow a) = $(hashQ "PrimFPow") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimLogBase a) = $(hashQ "PrimLogBase") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimAtan2 a) = $(hashQ "PrimAtan2") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimTruncate a b) = $(hashQ "PrimTruncate") `hashWithSalt` hashFloatingType a `hashWithSalt` hashIntegralType b+hashPrimFun (PrimRound a b) = $(hashQ "PrimRound") `hashWithSalt` hashFloatingType a `hashWithSalt` hashIntegralType b+hashPrimFun (PrimFloor a b) = $(hashQ "PrimFloor") `hashWithSalt` hashFloatingType a `hashWithSalt` hashIntegralType b+hashPrimFun (PrimCeiling a b) = $(hashQ "PrimCeiling") `hashWithSalt` hashFloatingType a `hashWithSalt` hashIntegralType b+hashPrimFun (PrimIsNaN a) = $(hashQ "PrimIsNaN") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimIsInfinite a) = $(hashQ "PrimIsInfinite") `hashWithSalt` hashFloatingType a+hashPrimFun (PrimLt a) = $(hashQ "PrimLt") `hashWithSalt` hashScalarType a+hashPrimFun (PrimGt a) = $(hashQ "PrimGt") `hashWithSalt` hashScalarType a+hashPrimFun (PrimLtEq a) = $(hashQ "PrimLtEq") `hashWithSalt` hashScalarType a+hashPrimFun (PrimGtEq a) = $(hashQ "PrimGtEq") `hashWithSalt` hashScalarType a+hashPrimFun (PrimEq a) = $(hashQ "PrimEq") `hashWithSalt` hashScalarType a+hashPrimFun (PrimNEq a) = $(hashQ "PrimNEq") `hashWithSalt` hashScalarType a+hashPrimFun (PrimMax a) = $(hashQ "PrimMax") `hashWithSalt` hashScalarType a+hashPrimFun (PrimMin a) = $(hashQ "PrimMin") `hashWithSalt` hashScalarType a+hashPrimFun (PrimFromIntegral a b) = $(hashQ "PrimFromIntegral") `hashWithSalt` hashIntegralType a `hashWithSalt` hashNumType b+hashPrimFun (PrimToFloating a b) = $(hashQ "PrimToFloating") `hashWithSalt` hashNumType a `hashWithSalt` hashFloatingType b+hashPrimFun (PrimCoerce a b) = $(hashQ "PrimCoerce") `hashWithSalt` hashScalarType a `hashWithSalt` hashScalarType b+hashPrimFun PrimLAnd = $(hashQ "PrimLAnd")+hashPrimFun PrimLOr = $(hashQ "PrimLOr")+hashPrimFun PrimLNot = $(hashQ "PrimLNot")+hashPrimFun PrimOrd = $(hashQ "PrimOrd")+hashPrimFun PrimChr = $(hashQ "PrimChr")+hashPrimFun PrimBoolToInt = $(hashQ "PrimBoolToInt")+++-- TLM: We need to include the depth of the branches in the pair case, otherwise+-- we are getting a collision at @hash t == hash (t,(t,t))@.+--+hashTupleType :: TupleType t -> Int+hashTupleType UnitTuple = $(hashQ "UnitTuple")+hashTupleType (SingleTuple t) = $(hashQ "SingleTuple") `hashWithSalt` hashScalarType t+hashTupleType (PairTuple a b) = $(hashQ "PairTuple") `hashWithSalt` hashTupleType a `hashWithSalt` depthTupleType a+ `hashWithSalt` hashTupleType b `hashWithSalt` depthTupleType b++depthTupleType :: TupleType t -> Int+depthTupleType UnitTuple = 0+depthTupleType SingleTuple{} = 1+depthTupleType (PairTuple a b) = depthTupleType a + depthTupleType b++hashScalarType :: ScalarType t -> Int+hashScalarType (NumScalarType t) = $(hashQ "NumScalarType") `hashWithSalt` hashNumType t+hashScalarType (NonNumScalarType t) = $(hashQ "NonNumScalarType") `hashWithSalt` hashNonNumType t++hashBoundedType :: BoundedType t -> Int+hashBoundedType (IntegralBoundedType t) = $(hashQ "IntegralBoundedType") `hashWithSalt` hashIntegralType t+hashBoundedType (NonNumBoundedType t) = $(hashQ "NonNumBoundedType") `hashWithSalt` hashNonNumType t++hashNonNumType :: NonNumType t -> Int+hashNonNumType TypeBool{} = $(hashQ "Bool")+hashNonNumType TypeChar{} = $(hashQ "Char")+hashNonNumType TypeCChar{} = $(hashQ "CChar")+hashNonNumType TypeCSChar{} = $(hashQ "CSChar")+hashNonNumType TypeCUChar{} = $(hashQ "CUChar")++hashNumType :: NumType t -> Int+hashNumType (IntegralNumType t) = $(hashQ "IntegralNumType") `hashWithSalt` hashIntegralType t+hashNumType (FloatingNumType t) = $(hashQ "FloatingNumType") `hashWithSalt` hashFloatingType t++hashIntegralType :: IntegralType t -> Int+hashIntegralType TypeInt{} = $(hashQ "Int")+hashIntegralType TypeInt8{} = $(hashQ "Int8")+hashIntegralType TypeInt16{} = $(hashQ "Int16")+hashIntegralType TypeInt32{} = $(hashQ "Int32")+hashIntegralType TypeInt64{} = $(hashQ "Int64")+hashIntegralType TypeWord{} = $(hashQ "Word")+hashIntegralType TypeWord8{} = $(hashQ "Word8")+hashIntegralType TypeWord16{} = $(hashQ "Word16")+hashIntegralType TypeWord32{} = $(hashQ "Word32")+hashIntegralType TypeWord64{} = $(hashQ "Word64")+hashIntegralType TypeCShort{} = $(hashQ "CShort")+hashIntegralType TypeCUShort{} = $(hashQ "CUShort")+hashIntegralType TypeCInt{} = $(hashQ "CInt")+hashIntegralType TypeCUInt{} = $(hashQ "CUInt")+hashIntegralType TypeCLong{} = $(hashQ "CLong")+hashIntegralType TypeCULong{} = $(hashQ "CULong")+hashIntegralType TypeCLLong{} = $(hashQ "CLLong")+hashIntegralType TypeCULLong{} = $(hashQ "CULLong")++hashFloatingType :: FloatingType t -> Int+hashFloatingType TypeFloat{} = $(hashQ "Float")+hashFloatingType TypeDouble{} = $(hashQ "Double")+hashFloatingType TypeCFloat{} = $(hashQ "CFloat")+hashFloatingType TypeCDouble{} = $(hashQ "CDouble")+++-- Auxiliary+-- ---------++-- Discriminate binary functions that commute, and if so return the operands in+-- a stable ordering such that matching recognises expressions modulo+-- commutativity.+--+commutes+ :: forall acc env aenv a r.+ HashAcc acc+ -> PrimFun (a -> r)+ -> PreOpenExp acc env aenv a+ -> Maybe (PreOpenExp acc env aenv a)+commutes h f x = case f of+ PrimAdd{} -> Just (swizzle x)+ PrimMul{} -> Just (swizzle x)+ PrimBAnd{} -> Just (swizzle x)+ PrimBOr{} -> Just (swizzle x)+ PrimBXor{} -> Just (swizzle x)+ PrimEq{} -> Just (swizzle x)+ PrimNEq{} -> Just (swizzle x)+ PrimMax{} -> Just (swizzle x)+ PrimMin{} -> Just (swizzle x)+ PrimLAnd -> Just (swizzle x)+ PrimLOr -> Just (swizzle x)+ _ -> Nothing+ where+ swizzle :: PreOpenExp acc env aenv (a',a') -> PreOpenExp acc env aenv (a',a')+ swizzle exp+ | Tuple (NilTup `SnocTup` a `SnocTup` b) <- exp+ , hashPreOpenExp h a > hashPreOpenExp h b = Tuple (NilTup `SnocTup` b `SnocTup` a)+ --+ | otherwise = exp+
+ Data/Array/Accelerate/Analysis/Hash/TH.hs view
@@ -0,0 +1,30 @@+-- |+-- Module : Data.Array.Accelerate.Analysis.Hash.TH+-- Copyright : [2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--++module Data.Array.Accelerate.Analysis.Hash.TH (++ hashQ,+ hashWithSaltQ,++) where++import Data.Hashable+import Language.Haskell.TH+++hashQ :: Hashable a => a -> ExpQ+hashQ = intE . hash++hashWithSaltQ :: Hashable a => Int -> a -> ExpQ+hashWithSaltQ s x = intE (hashWithSalt s x)++intE :: Int -> ExpQ+intE = litE . integerL . fromIntegral+
Data/Array/Accelerate/Analysis/Match.hs view
@@ -2,7 +2,6 @@ {-# LANGUAGE PatternGuards #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeOperators #-} {-# OPTIONS_HADDOCK hide #-} -- |@@ -30,28 +29,22 @@ matchIdx, matchTupleType, matchIntegralType, matchFloatingType, matchNumType, matchScalarType, - -- hashing expressions- HashAcc,- hashPreOpenAcc, hashOpenAcc,- hashPreOpenExp, hashOpenExp,- hashPreOpenFun,- ) where -- standard library-import Prelude hiding ( exp ) import Data.Maybe import Data.Typeable-import Data.Hashable-import System.Mem.StableName import System.IO.Unsafe ( unsafePerformIO )+import System.Mem.StableName+import Prelude hiding ( exp ) -- friends import Data.Array.Accelerate.AST-import Data.Array.Accelerate.Type-import Data.Array.Accelerate.Array.Sugar+import Data.Array.Accelerate.Analysis.Hash import Data.Array.Accelerate.Array.Representation ( SliceIndex(..) )+import Data.Array.Accelerate.Array.Sugar import Data.Array.Accelerate.Product+import Data.Array.Accelerate.Type -- The type of matching array computations@@ -246,20 +239,18 @@ , Just Refl <- matchAcc a1 a2 = Just Refl - match (Stencil f1 b1 (a1 :: acc aenv (Array sh1 e1)))- (Stencil f2 b2 (a2 :: acc aenv (Array sh2 e2)))+ match (Stencil f1 b1 a1) (Stencil f2 b2 a2) | Just Refl <- matchFun f1 f2 , Just Refl <- matchAcc a1 a2- , matchBoundary (eltType (undefined::e1)) b1 b2+ , matchBoundary matchAcc hashAcc b1 b2 = Just Refl - match (Stencil2 f1 b1 (a1 :: acc aenv (Array sh1 e1 )) b2 (a2 :: acc aenv (Array sh2 e2 )))- (Stencil2 f2 b1' (a1' :: acc aenv (Array sh1' e1')) b2' (a2':: acc aenv (Array sh2' e2')))+ match (Stencil2 f1 b1 a1 b2 a2) (Stencil2 f2 b1' a1' b2' a2') | Just Refl <- matchFun f1 f2 , Just Refl <- matchAcc a1 a1' , Just Refl <- matchAcc a2 a2'- , matchBoundary (eltType (undefined::e1)) b1 b1'- , matchBoundary (eltType (undefined::e2)) b2 b2'+ , matchBoundary matchAcc hashAcc b1 b1'+ , matchBoundary matchAcc hashAcc b2 b2' = Just Refl -- match (Collect s1) (Collect s2)@@ -313,12 +304,22 @@ -- Match stencil boundaries ---matchBoundary :: TupleType e -> Boundary e -> Boundary e -> Bool-matchBoundary ty (Constant s) (Constant t) = matchConst ty s t-matchBoundary _ Wrap Wrap = True-matchBoundary _ Clamp Clamp = True-matchBoundary _ Mirror Mirror = True-matchBoundary _ _ _ = False+matchBoundary+ :: forall acc aenv sh t. Elt t+ => MatchAcc acc+ -> HashAcc acc+ -> PreBoundary acc aenv (Array sh t)+ -> PreBoundary acc aenv (Array sh t)+ -> Bool+matchBoundary _ _ Clamp Clamp = True+matchBoundary _ _ Mirror Mirror = True+matchBoundary _ _ Wrap Wrap = True+matchBoundary _ _ (Constant s) (Constant t) = matchConst (eltType (undefined::t)) s t+matchBoundary m h (Function f) (Function g)+ | Just Refl <- matchPreOpenFun m h f g+ = True+matchBoundary _ _ _ _+ = False {--@@ -752,6 +753,7 @@ matchPrimFun (PrimFloor _ s) (PrimFloor _ t) = matchIntegralType s t matchPrimFun (PrimCeiling _ s) (PrimCeiling _ t) = matchIntegralType s t matchPrimFun (PrimIsNaN _) (PrimIsNaN _) = Just Refl+matchPrimFun (PrimIsInfinite _) (PrimIsInfinite _) = Just Refl matchPrimFun (PrimLt _) (PrimLt _) = Just Refl matchPrimFun (PrimGt _) (PrimGt _) = Just Refl matchPrimFun (PrimLtEq _) (PrimLtEq _) = Just Refl@@ -823,6 +825,7 @@ matchPrimFun' (PrimFloor s _) (PrimFloor t _) = matchFloatingType s t matchPrimFun' (PrimCeiling s _) (PrimCeiling t _) = matchFloatingType s t matchPrimFun' (PrimIsNaN s) (PrimIsNaN t) = matchFloatingType s t+matchPrimFun' (PrimIsInfinite s) (PrimIsInfinite t) = matchFloatingType s t matchPrimFun' (PrimMax _) (PrimMax _) = Just Refl matchPrimFun' (PrimMin _) (PrimMin _) = Just Refl matchPrimFun' (PrimFromIntegral s _) (PrimFromIntegral t _) = matchIntegralType s t@@ -928,296 +931,4 @@ matchNonNumType (TypeCSChar _) (TypeCSChar _) = Just Refl matchNonNumType (TypeCUChar _) (TypeCUChar _) = Just Refl matchNonNumType _ _ = Nothing----- Discriminate binary functions that commute, and if so return the operands in--- a stable ordering such that matching recognises expressions modulo--- commutativity.----commutes- :: forall acc env aenv a r.- HashAcc acc- -> PrimFun (a -> r)- -> PreOpenExp acc env aenv a- -> Maybe (PreOpenExp acc env aenv a)-commutes h f x = case f of- PrimAdd _ -> Just (swizzle x)- PrimMul _ -> Just (swizzle x)- PrimBAnd _ -> Just (swizzle x)- PrimBOr _ -> Just (swizzle x)- PrimBXor _ -> Just (swizzle x)- PrimEq _ -> Just (swizzle x)- PrimNEq _ -> Just (swizzle x)- PrimMax _ -> Just (swizzle x)- PrimMin _ -> Just (swizzle x)- PrimLAnd -> Just (swizzle x)- PrimLOr -> Just (swizzle x)- _ -> Nothing- where- swizzle :: PreOpenExp acc env aenv (a',a') -> PreOpenExp acc env aenv (a',a')- swizzle exp- | Tuple (NilTup `SnocTup` a `SnocTup` b) <- exp- , hashPreOpenExp h a > hashPreOpenExp h b = Tuple (NilTup `SnocTup` b `SnocTup` a)- --- | otherwise = exp----- Hashing--- =======--hashIdx :: Idx env t -> Int-hashIdx = hash . idxToInt--hashTupleIdx :: TupleIdx tup e -> Int-hashTupleIdx = hash . tupleIdxToInt----- Array computations--- --------------------type HashAcc acc = forall aenv a. acc aenv a -> Int---hashOpenAcc :: OpenAcc aenv arrs -> Int-hashOpenAcc (OpenAcc pacc) = hashPreOpenAcc hashOpenAcc pacc--{---hashPreOpenSeq :: forall acc aenv senv arrs. HashAcc acc -> PreOpenSeq acc aenv senv arrs -> Int-hashPreOpenSeq hashAcc s =- let- hashA :: Int -> acc aenv' a -> Int- hashA salt = hashWithSalt salt . hashAcc-- hashE :: Int -> PreOpenExp acc env' aenv' e -> Int- hashE salt = hashWithSalt salt . hashPreOpenExp hashAcc-- hashAF :: Int -> PreOpenAfun acc aenv' f -> Int- hashAF salt = hashWithSalt salt . hashAfun hashAcc-- hashF :: Int -> PreOpenFun acc env' aenv' f -> Int- hashF salt = hashWithSalt salt . hashPreOpenFun hashAcc-- hashS :: Int -> PreOpenSeq acc aenv senv' arrs' -> Int- hashS salt = hashWithSalt salt . hashPreOpenSeq hashAcc-- hashVar :: Int -> Idx senv' a -> Int- hashVar salt = hashWithSalt salt . idxToInt-- hashP :: Int -> Producer acc aenv senv a -> Int- hashP salt p =- case p of- StreamIn arrs -> unsafePerformIO $! hashStableName `fmap` makeStableName arrs- ToSeq spec _ acc -> hashWithSalt salt "ToSeq" `hashA` acc `hashWithSalt` show spec- MapSeq f x -> hashWithSalt salt "MapSeq" `hashAF` f `hashVar` x- ChunkedMapSeq f x -> hashWithSalt salt "ChunkedMapSeq" `hashAF` f `hashVar` x- ZipWithSeq f x y -> hashWithSalt salt "ZipWithSeq" `hashAF` f `hashVar` x `hashVar` y- ScanSeq f e x -> hashWithSalt salt "ScanSeq" `hashF` f `hashE` e `hashVar` x-- hashC :: Int -> Consumer acc aenv senv' a -> Int- hashC salt c =- case c of- FoldSeq f e x -> hashWithSalt salt "FoldSeq" `hashF` f `hashE` e `hashVar` x- FoldSeqFlatten f acc x -> hashWithSalt salt "FoldSeqFlatten" `hashAF` f `hashA` acc `hashVar` x- Stuple t -> hash "Stuple" `hashWithSalt` hashAtuple (hashC salt) t-- in case s of- Producer p s' -> hash "Producer" `hashP` p `hashS` s'- Consumer c -> hash "Consumer" `hashC` c- Reify ix -> hash "Reify" `hashVar` ix---}---hashPreOpenAcc :: forall acc aenv arrs. HashAcc acc -> PreOpenAcc acc aenv arrs -> Int-hashPreOpenAcc hashAcc pacc =- let- hashA :: Int -> acc aenv' a -> Int- hashA salt = hashWithSalt salt . hashAcc-- hashE :: Int -> PreOpenExp acc env' aenv' e -> Int- hashE salt = hashWithSalt salt . hashPreOpenExp hashAcc-- hashF :: Int -> PreOpenFun acc env' aenv' f -> Int- hashF salt = hashWithSalt salt . hashPreOpenFun hashAcc-- -- hashS :: Int -> PreOpenSeq acc aenv senv arrs -> Int- -- hashS salt = hashWithSalt salt . hashPreOpenSeq hashAcc-- in case pacc of- Alet bnd body -> hash "Alet" `hashA` bnd `hashA` body- Avar v -> hash "Avar" `hashWithSalt` hashIdx v- Atuple t -> hash "Atuple" `hashWithSalt` hashAtuple hashAcc t- Aprj ix a -> hash "Aprj" `hashWithSalt` hashTupleIdx ix `hashA` a- Apply f a -> hash "Apply" `hashWithSalt` hashAfun hashAcc f `hashA` a- Aforeign _ f a -> hash "Aforeign" `hashWithSalt` hashAfun hashAcc f `hashA` a- Use a -> hash "Use" `hashWithSalt` hashArrays (arrays (undefined::arrs)) a- Awhile p f a -> hash "Awhile" `hashWithSalt` hashAfun hashAcc f `hashWithSalt` hashAfun hashAcc p `hashA` a- Unit e -> hash "Unit" `hashE` e- Generate e f -> hash "Generate" `hashE` e `hashF` f- Acond e a1 a2 -> hash "Acond" `hashE` e `hashA` a1 `hashA` a2- Reshape sh a -> hash "Reshape" `hashE` sh `hashA` a- Transform sh f1 f2 a -> hash "Transform" `hashE` sh `hashF` f1 `hashF` f2 `hashA` a- Replicate spec ix a -> hash "Replicate" `hashE` ix `hashA` a `hashWithSalt` show spec- Slice spec a ix -> hash "Slice" `hashE` ix `hashA` a `hashWithSalt` show spec- Map f a -> hash "Map" `hashF` f `hashA` a- ZipWith f a1 a2 -> hash "ZipWith" `hashF` f `hashA` a1 `hashA` a2- Fold f e a -> hash "Fold" `hashF` f `hashE` e `hashA` a- Fold1 f a -> hash "Fold1" `hashF` f `hashA` a- FoldSeg f e a s -> hash "FoldSeg" `hashF` f `hashE` e `hashA` a `hashA` s- Fold1Seg f a s -> hash "Fold1Seg" `hashF` f `hashA` a `hashA` s- Scanl f e a -> hash "Scanl" `hashF` f `hashE` e `hashA` a- Scanl' f e a -> hash "Scanl'" `hashF` f `hashE` e `hashA` a- Scanl1 f a -> hash "Scanl1" `hashF` f `hashA` a- Scanr f e a -> hash "Scanr" `hashF` f `hashE` e `hashA` a- Scanr' f e a -> hash "Scanr'" `hashF` f `hashE` e `hashA` a- Scanr1 f a -> hash "Scanr1" `hashF` f `hashA` a- Backpermute sh f a -> hash "Backpermute" `hashF` f `hashE` sh `hashA` a- Permute f1 a1 f2 a2 -> hash "Permute" `hashF` f1 `hashA` a1 `hashF` f2 `hashA` a2- Stencil f b a -> hash "Stencil" `hashF` f `hashA` a `hashWithSalt` hashBoundary a b- Stencil2 f b1 a1 b2 a2 -> hash "Stencil2" `hashF` f `hashA` a1 `hashA` a2 `hashWithSalt` hashBoundary a1 b1 `hashWithSalt` hashBoundary a2 b2- -- Collect s -> hash "Seq" `hashS` s---hashArrays :: ArraysR a -> a -> Int-hashArrays ArraysRunit () = hash ()-hashArrays (ArraysRpair r1 r2) (a1, a2) = hash ( hashArrays r1 a1, hashArrays r2 a2)-hashArrays ArraysRarray ad = unsafePerformIO $! hashStableName `fmap` makeStableName ad--hashAtuple :: HashAcc acc -> Atuple (acc aenv) a -> Int-hashAtuple _ NilAtup = hash "NilAtup"-hashAtuple h (SnocAtup t a) = hash "SnocAtup" `hashWithSalt` hashAtuple h t `hashWithSalt` h a--hashAfun :: HashAcc acc -> PreOpenAfun acc aenv f -> Int-hashAfun h (Abody b) = hash "Abody" `hashWithSalt` h b-hashAfun h (Alam f) = hash "Alam" `hashWithSalt` hashAfun h f--hashBoundary :: forall acc aenv sh e. Elt e => acc aenv (Array sh e) -> Boundary (EltRepr e) -> Int-hashBoundary _ Wrap = hash "Wrap"-hashBoundary _ Clamp = hash "Clamp"-hashBoundary _ Mirror = hash "Mirror"-hashBoundary _ (Constant c) = hash "Constant" `hashWithSalt` show (toElt c :: e)----- Scalar expressions--- --------------------hashOpenExp :: OpenExp env aenv exp -> Int-hashOpenExp = hashPreOpenExp hashOpenAcc--hashPreOpenExp :: forall acc env aenv exp. HashAcc acc -> PreOpenExp acc env aenv exp -> Int-hashPreOpenExp hashAcc exp =- let- hashA :: Int -> acc aenv' a -> Int- hashA salt = hashWithSalt salt . hashAcc-- hashE :: Int -> PreOpenExp acc env' aenv' e -> Int- hashE salt = hashWithSalt salt . hashPreOpenExp hashAcc-- in case exp of- Let bnd body -> hash "Let" `hashE` bnd `hashE` body- Var ix -> hash "Var" `hashWithSalt` hashIdx ix- Const c -> hash "Const" `hashWithSalt` show (toElt c :: exp)- Tuple t -> hash "Tuple" `hashWithSalt` hashTuple hashAcc t- Prj i e -> hash "Prj" `hashWithSalt` hashTupleIdx i `hashE` e- IndexAny -> hash "IndexAny"- IndexNil -> hash "IndexNil"- IndexCons sl a -> hash "IndexCons" `hashE` sl `hashE` a- IndexHead sl -> hash "IndexHead" `hashE` sl- IndexTail sl -> hash "IndexTail" `hashE` sl- IndexSlice spec ix sh -> hash "IndexSlice" `hashE` ix `hashE` sh `hashWithSalt` show spec- IndexFull spec ix sl -> hash "IndexFull" `hashE` ix `hashE` sl `hashWithSalt` show spec- ToIndex sh i -> hash "ToIndex" `hashE` sh `hashE` i- FromIndex sh i -> hash "FromIndex" `hashE` sh `hashE` i- Cond c t e -> hash "Cond" `hashE` c `hashE` t `hashE` e- While p f x -> hash "While" `hashWithSalt` hashPreOpenFun hashAcc p `hashWithSalt` hashPreOpenFun hashAcc f `hashE` x- PrimApp f x -> hash "PrimApp" `hashWithSalt` hashPrimFun f `hashE` fromMaybe x (commutes hashAcc f x)- PrimConst c -> hash "PrimConst" `hashWithSalt` hashPrimConst c- Index a ix -> hash "Index" `hashA` a `hashE` ix- LinearIndex a ix -> hash "LinearIndex" `hashA` a `hashE` ix- Shape a -> hash "Shape" `hashA` a- ShapeSize sh -> hash "ShapeSize" `hashE` sh- Intersect sa sb -> hash "Intersect" `hashE` sa `hashE` sb- Union sa sb -> hash "Union" `hashE` sa `hashE` sb- Foreign _ f e -> hash "Foreign" `hashWithSalt` hashPreOpenFun hashAcc f `hashE` e---hashPreOpenFun :: HashAcc acc -> PreOpenFun acc env aenv f -> Int-hashPreOpenFun h (Body e) = hash "Body" `hashWithSalt` hashPreOpenExp h e-hashPreOpenFun h (Lam f) = hash "Lam" `hashWithSalt` hashPreOpenFun h f--hashTuple :: HashAcc acc -> Tuple (PreOpenExp acc env aenv) e -> Int-hashTuple _ NilTup = hash "NilTup"-hashTuple h (SnocTup t e) = hash "SnocTup" `hashWithSalt` hashTuple h t `hashWithSalt` hashPreOpenExp h e---hashPrimConst :: PrimConst c -> Int-hashPrimConst PrimMinBound{} = hash "PrimMinBound"-hashPrimConst PrimMaxBound{} = hash "PrimMaxBound"-hashPrimConst PrimPi{} = hash "PrimPi"--hashPrimFun :: PrimFun f -> Int-hashPrimFun PrimAdd{} = hash "PrimAdd"-hashPrimFun PrimSub{} = hash "PrimSub"-hashPrimFun PrimMul{} = hash "PrimMul"-hashPrimFun PrimNeg{} = hash "PrimNeg"-hashPrimFun PrimAbs{} = hash "PrimAbs"-hashPrimFun PrimSig{} = hash "PrimSig"-hashPrimFun PrimQuot{} = hash "PrimQuot"-hashPrimFun PrimRem{} = hash "PrimRem"-hashPrimFun PrimQuotRem{} = hash "PrimQuotRem"-hashPrimFun PrimIDiv{} = hash "PrimIDiv"-hashPrimFun PrimMod{} = hash "PrimMod"-hashPrimFun PrimDivMod{} = hash "PrimDivMod"-hashPrimFun PrimBAnd{} = hash "PrimBAnd"-hashPrimFun PrimBOr{} = hash "PrimBOr"-hashPrimFun PrimBXor{} = hash "PrimBXor"-hashPrimFun PrimBNot{} = hash "PrimBNot"-hashPrimFun PrimBShiftL{} = hash "PrimBShiftL"-hashPrimFun PrimBShiftR{} = hash "PrimBShiftR"-hashPrimFun PrimBRotateL{} = hash "PrimBRotateL"-hashPrimFun PrimBRotateR{} = hash "PrimBRotateR"-hashPrimFun PrimPopCount{} = hash "PrimPopCount"-hashPrimFun PrimCountLeadingZeros{} = hash "PrimCountLeadingZeros"-hashPrimFun PrimCountTrailingZeros{} = hash "PrimCountTrailingZeros"-hashPrimFun PrimFDiv{} = hash "PrimFDiv"-hashPrimFun PrimRecip{} = hash "PrimRecip"-hashPrimFun PrimSin{} = hash "PrimSin"-hashPrimFun PrimCos{} = hash "PrimCos"-hashPrimFun PrimTan{} = hash "PrimTan"-hashPrimFun PrimAsin{} = hash "PrimAsin"-hashPrimFun PrimAcos{} = hash "PrimAcos"-hashPrimFun PrimAtan{} = hash "PrimAtan"-hashPrimFun PrimSinh{} = hash "PrimSinh"-hashPrimFun PrimCosh{} = hash "PrimCosh"-hashPrimFun PrimTanh{} = hash "PrimTanh"-hashPrimFun PrimAsinh{} = hash "PrimAsinh"-hashPrimFun PrimAcosh{} = hash "PrimAcosh"-hashPrimFun PrimAtanh{} = hash "PrimAtanh"-hashPrimFun PrimExpFloating{} = hash "PrimExpFloating"-hashPrimFun PrimSqrt{} = hash "PrimSqrt"-hashPrimFun PrimLog{} = hash "PrimLog"-hashPrimFun PrimFPow{} = hash "PrimFPow"-hashPrimFun PrimLogBase{} = hash "PrimLogBase"-hashPrimFun PrimAtan2{} = hash "PrimAtan2"-hashPrimFun PrimTruncate{} = hash "PrimTruncate"-hashPrimFun PrimRound{} = hash "PrimRound"-hashPrimFun PrimFloor{} = hash "PrimFloor"-hashPrimFun PrimCeiling{} = hash "PrimCeiling"-hashPrimFun PrimIsNaN{} = hash "PrimIsNaN"-hashPrimFun PrimLt{} = hash "PrimLt"-hashPrimFun PrimGt{} = hash "PrimGt"-hashPrimFun PrimLtEq{} = hash "PrimLtEq"-hashPrimFun PrimGtEq{} = hash "PrimGtEq"-hashPrimFun PrimEq{} = hash "PrimEq"-hashPrimFun PrimNEq{} = hash "PrimNEq"-hashPrimFun PrimMax{} = hash "PrimMax"-hashPrimFun PrimMin{} = hash "PrimMin"-hashPrimFun PrimFromIntegral{} = hash "PrimFromIntegral"-hashPrimFun PrimToFloating{} = hash "PrimToFloating"-hashPrimFun PrimCoerce{} = hash "PrimCoerce"-hashPrimFun PrimLAnd = hash "PrimLAnd"-hashPrimFun PrimLOr = hash "PrimLOr"-hashPrimFun PrimLNot = hash "PrimLNot"-hashPrimFun PrimOrd = hash "PrimOrd"-hashPrimFun PrimChr = hash "PrimChr"-hashPrimFun PrimBoolToInt = hash "PrimBoolToInt"
Data/Array/Accelerate/Array/Data.hs view
@@ -46,6 +46,7 @@ import Data.Array.Accelerate.Type import Data.Array.Accelerate.Debug.Flags+import Data.Array.Accelerate.Debug.Monitoring import Data.Array.Accelerate.Debug.Trace -- standard libraries@@ -774,6 +775,7 @@ new <- readIORef __mallocForeignPtrBytes ptr <- new bytes traceIO dump_gc $ printf "gc: allocated new host array (size=%d, ptr=%s)" bytes (show ptr)+ didAllocateBytesLocal (fromIntegral bytes) return (castForeignPtr ptr) -- | Register the given function as the callback to use to allocate new array@@ -800,6 +802,7 @@ -- to add a finaliser to the plain ForeignPtr. For our purposes this is fine, -- since in Accelerate finalisers are handled using Lifetime --+{-# INLINE mallocPlainForeignPtrBytesAligned #-} mallocPlainForeignPtrBytesAligned :: Int -> IO (ForeignPtr a) mallocPlainForeignPtrBytesAligned (I# size) = IO $ \s -> case newAlignedPinnedByteArray# size 16# s of
Data/Array/Accelerate/Array/Remote/LRU.hs view
@@ -34,25 +34,26 @@ ) where -import Data.Functor-import Data.Maybe ( isNothing )-import Data.Proxy+import Control.Concurrent.MVar ( MVar, newMVar, takeMVar, putMVar, mkWeakMVar ) import Control.Monad ( filterM ) import Control.Monad.Catch import Control.Monad.IO.Class ( MonadIO, liftIO )-import Control.Concurrent.MVar ( MVar, newMVar, takeMVar, putMVar, mkWeakMVar )+import Data.Functor+import Data.Int ( Int64 )+import Data.Maybe ( isNothing )+import Data.Proxy+import Foreign.Storable ( sizeOf ) import System.CPUTime import System.Mem.Weak ( Weak, deRefWeak, finalize ) import Prelude hiding ( lookup )- import qualified Data.HashTable.IO as HT -import qualified Data.Array.Accelerate.Debug as D-import Data.Array.Accelerate.Error ( internalError ) import Data.Array.Accelerate.Array.Data ( ArrayData, touchArrayData ) import Data.Array.Accelerate.Array.Remote.Class import Data.Array.Accelerate.Array.Remote.Table ( StableArray, makeWeakArrayData )+import Data.Array.Accelerate.Error ( internalError ) import qualified Data.Array.Accelerate.Array.Remote.Table as Basic+import qualified Data.Array.Accelerate.Debug as D -- We build cached memory tables on top of a basic memory table.@@ -185,13 +186,13 @@ -- This has similar behaviour to malloc in Data.Array.Accelerate.Array.Memory.Table -- but also will copy remote arrays back to main memory in order to make space. ----- The third argument indicates that the array should be considered frozen.--- That is to say the array arrays contents will never change. In the event that--- the array has to be evicted from the remote memory, the copy already residing--- in host memory should be considered valid.+-- The third argument indicates that the array should be considered frozen. That+-- is to say that the array contents will never change. In the event that the+-- array has to be evicted from the remote memory, the copy already residing in+-- host memory should be considered valid. ----- If malloc is called on an array that is already contained within the cache,--- it becomes a no-op.+-- If this function is called on an array that is already contained within the+-- cache, this is a no-op. -- -- On return, 'True' indicates that we allocated some remote memory, and 'False' -- indicates that we did not need to.@@ -199,9 +200,9 @@ malloc :: forall a e m task. (PrimElt e a, RemoteMemory m, MonadIO m, Task task) => MemoryTable (RemotePtr m) task -> ArrayData e- -> Bool -- ^True if host array is frozen.+ -> Bool -- ^ True if host array is frozen. -> Int- -> m Bool+ -> m Bool -- ^ Was the array allocated successfully? malloc (MemoryTable mt ref weak_utbl) !ad !frozen !n = do ts <- liftIO $ getCPUTime key <- Basic.makeStableArray ad@@ -234,7 +235,8 @@ case mp of Nothing -> do success <- evictLRU utbl mt- if success then malloc' else $internalError "malloc" "Remote memory exhausted"+ if success then malloc'+ else $internalError "malloc" "Remote memory exhausted" Just p -> liftIO $ do key <- Basic.makeStableArray ad HT.insert utbl key usage@@ -264,6 +266,7 @@ Just arr -> do message ("evictLRU/evicting " ++ show sa) copyIfNecessary status n arr+ liftIO $ D.didEvictBytes (remoteBytes n weak_arr) liftIO $ Basic.freeStable (Proxy :: Proxy m) mt sa liftIO $ HT.insert utbl sa (Used ts Evicted count tasks n weak_arr) return True@@ -281,6 +284,9 @@ | Nothing <- prev -> return (Just (sa, used)) _ -> return prev eldest prev _ = return prev++ remoteBytes :: forall e a. PrimElt e a => Int -> Weak (ArrayData e) -> Int64+ remoteBytes n _ = fromIntegral n * fromIntegral (sizeOf (undefined::a)) evictable :: Status -> Bool evictable Clean = True
Data/Array/Accelerate/Array/Remote/Nursery.hs view
@@ -20,16 +20,16 @@ -- friends import Data.Array.Accelerate.Error-import qualified Data.Array.Accelerate.Debug as D+import qualified Data.Array.Accelerate.Debug as Debug -- libraries-import Prelude hiding ( lookup ) import Control.Concurrent.MVar import Data.Int import Data.IntMap ( IntMap ) import Data.Sequence ( Seq ) import Data.Word import System.Mem.Weak ( Weak )+import Prelude hiding ( lookup ) import qualified Data.IntMap.Strict as IM import qualified Data.Sequence as Seq import qualified Data.Traversable as Seq@@ -79,8 +79,10 @@ else Just vs -- re-insert the tail in case fmap Seq.viewl mv of- Just (v Seq.:< _) -> return ( N nrs' (sz - fromIntegral key) , Just v )- _ -> return ( nrs, Nothing )+ Just (v Seq.:< _) -> let sz' = sz - fromIntegral key in do+ Debug.setCurrentBytesNursery sz'+ return ( N nrs' sz', Just v )+ _ -> return ( nrs, Nothing ) -- | Add an entry to the nursery@@ -92,8 +94,10 @@ f Nothing = Just (Seq.singleton val) f (Just vs) = Just (vs Seq.|> val) in- modifyMVar_ ref $ \(N im sz) ->- return $! N (IM.alter f key im) (sz + fromIntegral key)+ modifyMVar_ ref $ \(N im sz) -> do+ let sz' = sz + fromIntegral key+ Debug.setCurrentBytesNursery sz'+ return $! N (IM.alter f key im) sz' -- | Delete all entries from the nursery@@ -103,6 +107,7 @@ cleanup delete !ref = do message "nursery cleanup" modifyMVar_ ref $ \(N nrs _) -> do mapM_ (Seq.mapM delete) (IM.elems nrs)+ Debug.setCurrentBytesNursery 0 return ( N IM.empty 0 ) @@ -118,5 +123,5 @@ {-# INLINE message #-} message :: String -> IO ()-message msg = D.traceIO D.dump_gc ("gc: " ++ msg)+message msg = Debug.traceIO Debug.dump_gc ("gc: " ++ msg)
Data/Array/Accelerate/Array/Remote/Table.hs view
@@ -245,6 +245,7 @@ Just (RemoteArray _ !p !bytes) -> do message ("free/evict: " ++ show sa ++ " of " ++ showBytes bytes) N.insert bytes (castRemotePtr proxy p) nrs+ D.decreaseCurrentBytesRemote (fromIntegral bytes) mt `HT.delete` sa @@ -261,6 +262,7 @@ key <- makeStableArray arr weak <- liftIO $ makeWeakArrayData arr () (Just $ freeStable (Proxy :: Proxy m) mt key) message $ "insert: " ++ show key+ liftIO $ D.increaseCurrentBytesRemote (fromIntegral bytes) liftIO $ withMVar ref $ \tbl -> HT.insert tbl key (RemoteArray weak ptr bytes) @@ -280,7 +282,7 @@ key <- makeStableArray arr weak <- liftIO $ makeWeakArrayData arr () (Just $ remoteFinalizer weak_ref key) message $ "insertUnmanaged: " ++ show key- liftIO $ withMVar ref $ \tbl -> HT.insert tbl key (RemoteArray weak ptr 0)+ liftIO $ withMVar ref $ \tbl -> HT.insert tbl key (RemoteArray weak ptr 0) -- Removing entries@@ -297,6 +299,7 @@ -- that finalizers are often significantly delayed, it is worth our while -- traversing the table and explicitly freeing any dead entires. --+ D.didRemoteGC performGC yield mr <- deRefWeak weak_ref
Data/Array/Accelerate/Array/Representation.hs view
@@ -32,7 +32,6 @@ -- friends import Data.Array.Accelerate.Error-import Data.Array.Accelerate.Type -- standard library import GHC.Base ( quotInt, remInt )@@ -56,8 +55,6 @@ toIndex :: sh -> sh -> Int -- yield the index position in a linear, row-major representation of -- the array (first argument is the shape) fromIndex :: sh -> Int -> sh -- inverse of `toIndex`- bound :: sh -> sh -> Boundary e -> Either e sh- -- apply a boundary condition to an index iter :: sh -> (sh -> a) -> (a -> a -> a) -> a -> a -- iterate through the entire shape, applying the function in the@@ -87,7 +84,6 @@ size () = 1 toIndex () () = 0 fromIndex () _ = ()- bound () () _ = Right () iter () f _ _ = f () iter1 () f _ = f () @@ -119,6 +115,7 @@ r | rank sh == 0 = $indexCheck "fromIndex" i sz i | otherwise = i `remInt` sz +{-- bound (sh, sz) (ix, i) bndy | i < 0 = case bndy of Clamp -> next `addDim` 0@@ -133,7 +130,7 @@ | otherwise = next `addDim` i where -- This function is quite difficult to optimize due to the deep recursion- -- that is can generate with high-dimensional arrays. If we let 'next' be+ -- that it can generate with high-dimensional arrays. If we let 'next' be -- inlined into each alternative of the cases above the size of this -- function on an n-dimensional array will grow as 7^n. This quickly causes -- GHC's head to explode. See GHC Trac #10491 for more details.@@ -142,6 +139,7 @@ Right ds `addDim` d = Right (ds, d) Left e `addDim` _ = Left e+--} iter (sh, sz) f c r = iter sh (\ix -> iter' (ix,0)) c r where
Data/Array/Accelerate/Array/Sugar.hs view
@@ -1,5 +1,5 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleContexts #-}@@ -7,6 +7,7 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-}@@ -63,14 +64,15 @@ import Control.DeepSeq import Data.List ( intercalate, transpose ) import Data.Typeable- import GHC.Exts ( IsList )+import Language.Haskell.TH hiding ( Foreign ) import qualified GHC.Exts as GHC -- friends-import Data.Array.Accelerate.Type import Data.Array.Accelerate.Array.Data+import Data.Array.Accelerate.Error import Data.Array.Accelerate.Product+import Data.Array.Accelerate.Type import qualified Data.Array.Accelerate.Array.Representation as Repr @@ -552,7 +554,7 @@ => (EltRepr a -> EltRepr b -> EltRepr c) -> (a -> b -> c) {-# INLINE liftToElt2 #-}-liftToElt2 f = \x y -> toElt $ f (fromElt x) (fromElt y)+liftToElt2 f x y = toElt $ f (fromElt x) (fromElt y) sinkFromElt :: (Elt a, Elt b) => (a -> b)@@ -564,7 +566,7 @@ => (a -> b -> c) -> (EltRepr a -> EltRepr b -> EltRepr c) {-# INLINE sinkFromElt2 #-}-sinkFromElt2 f = \x y -> fromElt $ f (toElt x) (toElt y)+sinkFromElt2 f x y = fromElt $ f (toElt x) (toElt y) -- {-# RULES -- "fromElt/toElt" forall e. fromElt (toElt e) = e@@ -584,8 +586,14 @@ -- Backends should be able to produce a string representation of the foreign -- function for pretty printing, typically the name of the function. strForeign :: asm args -> String+ strForeign _ = "<foreign>" + -- Backends which want to support compile-time embedding must be able to lift+ -- the foreign function into Template Haskell+ liftForeign :: asm args -> Q (TExp (asm args))+ liftForeign _ = $internalError "liftForeign" "not supported by this backend" + -- Surface arrays -- -------------- @@ -943,6 +951,7 @@ go ArrayEltRcuchar (AD_CUChar ua) = rnf ua go (ArrayEltRpair r1 r2) (AD_Pair a1 a2) = go r1 a1 `seq` go r2 a2 `seq` () + -- |Scalars arrays hold a single element -- type Scalar e = Array DIM0 e@@ -1007,9 +1016,6 @@ -- |Inverse of 'toIndex'. fromIndex :: sh -> Int -> sh - -- |Apply a boundary condition to an index.- bound :: sh -> sh -> Boundary a -> Either a sh- -- |Iterate through the entire shape, applying the function; third argument -- combines results and fourth is returned in case of an empty iteration -- space; the index space is traversed in row-major order.@@ -1047,10 +1053,6 @@ union sh1 sh2 = toElt (Repr.union (fromElt sh1) (fromElt sh2)) fromIndex sh ix = toElt (Repr.fromIndex (fromElt sh) ix) toIndex sh ix = Repr.toIndex (fromElt sh) (fromElt ix)-- bound sh ix bndy = case Repr.bound (fromElt sh) (fromElt ix) bndy of- Left v -> Left v- Right ix' -> Right $ toElt ix' iter sh f c r = Repr.iter (fromElt sh) (f . toElt) c r iter1 sh f r = Repr.iter1 (fromElt sh) (f . toElt) r
Data/Array/Accelerate/Array/Unique.hs view
@@ -57,6 +57,7 @@ -- | Create a new UniqueArray --+{-# INLINE newUniqueArray #-} newUniqueArray :: ForeignPtr e -> IO (UniqueArray e) newUniqueArray fp = UniqueArray <$> newUnique <*> newLifetime fp @@ -67,6 +68,7 @@ -- the action and use it after the action completes. All uses of the pointer -- should be inside the bracketed function. --+{-# INLINE withUniqueArrayPtr #-} withUniqueArrayPtr :: UniqueArray a -> (Ptr a -> IO b) -> IO b withUniqueArrayPtr ua go = withLifetime (uniqueArrayData ua) $ \fp -> withForeignPtr fp go@@ -80,6 +82,7 @@ -- -- See also: 'unsafeGetValue', 'unsafeForeignPtrToPtr'. --+{-# INLINE unsafeUniqueArrayPtr #-} unsafeUniqueArrayPtr :: UniqueArray a -> Ptr a unsafeUniqueArrayPtr = unsafeForeignPtrToPtr . unsafeGetValue . uniqueArrayData @@ -89,6 +92,7 @@ -- -- See: [Unique array strictness] --+{-# INLINE touchUniqueArray #-} touchUniqueArray :: UniqueArray a -> IO () touchUniqueArray = touchLifetime . uniqueArrayData
Data/Array/Accelerate/Async.hs view
@@ -75,7 +75,7 @@ {-# INLINE poll #-} poll :: Async a -> IO (Maybe a) poll (Async _ var) =- maybe (return Nothing) (either throwIO (return . Just)) =<< tryTakeMVar var+ maybe (return Nothing) (either throwIO (return . Just)) =<< tryReadMVar var -- | Cancel a running asynchronous computation. --
Data/Array/Accelerate/Classes/Enum.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-missing-methods #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- |
Data/Array/Accelerate/Classes/FromIntegral.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MonoLocalBinds #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TemplateHaskell #-} -- |
Data/Array/Accelerate/Classes/Integral.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MonoLocalBinds #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- | -- Module : Data.Array.Accelerate.Classes.Integral
Data/Array/Accelerate/Classes/Real.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MonoLocalBinds #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-missing-methods #-} {-# OPTIONS_GHC -fno-warn-orphans #-}
Data/Array/Accelerate/Classes/RealFloat.hs view
@@ -5,6 +5,7 @@ {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE ViewPatterns #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- | -- Module : Data.Array.Accelerate.Classes.RealFloat@@ -26,11 +27,17 @@ import Data.Array.Accelerate.Smart import Data.Array.Accelerate.Type +import Data.Array.Accelerate.Data.Bits++import Data.Array.Accelerate.Classes.Eq import Data.Array.Accelerate.Classes.Floating+import Data.Array.Accelerate.Classes.FromIntegral+import Data.Array.Accelerate.Classes.Num+import Data.Array.Accelerate.Classes.Ord import Data.Array.Accelerate.Classes.RealFrac import Text.Printf-import Prelude ( String, error, undefined )+import Prelude ( (.), ($), String, error, undefined, otherwise ) import qualified Prelude as P @@ -54,7 +61,7 @@ floatRange _ = let (m,n) = P.floatRange (undefined::a) in (constant m, constant n) - -- | Return the significand and an appropriately scaled exponent. if+ -- | Return the significand and an appropriately scaled exponent. If -- @(m,n) = 'decodeFloat' x@ then @x = m*b^^n@, where @b@ is the -- floating-point radix ('floatRadix'). Furthermore, either @m@ and @n@ are -- both zero, or @b^(d-1) <= 'abs' m < b^d@, where @d = 'floatDigits' x@.@@ -62,15 +69,36 @@ -- | Inverse of 'decodeFloat' encodeFloat :: Exp Int64 -> Exp Int -> Exp a -- Integer+ default encodeFloat :: (FromIntegral Int a, FromIntegral Int64 a) => Exp Int64 -> Exp Int -> Exp a+ encodeFloat x e = fromIntegral x * (fromIntegral (floatRadix (undefined :: Exp a)) ** fromIntegral e) -- | Corresponds to the second component of 'decodeFloat' exponent :: Exp a -> Exp Int+ exponent x = let (m,n) = decodeFloat x+ in Exp $ Cond (m == 0)+ 0+ (n + floatDigits x) -- | Corresponds to the first component of 'decodeFloat' significand :: Exp a -> Exp a+ significand x = let (m,_) = decodeFloat x+ in encodeFloat m (negate (floatDigits x)) -- | Multiply a floating point number by an integer power of the radix scaleFloat :: Exp Int -> Exp a -> Exp a+ scaleFloat k x =+ Exp $ Cond (k == 0 || isFix) x+ $ encodeFloat m (n + clamp b)+ where+ isFix = x == 0 || isNaN x || isInfinite x+ (m,n) = decodeFloat x+ (l,h) = floatRange x+ d = floatDigits x+ b = h - l + 4*d+ -- n+k may overflow, which would lead to incorrect results, hence we clamp+ -- the scaling parameter. If (n+k) would be larger than h, (n + clamp b k)+ -- must be too, similar for smaller than (l-d).+ clamp bd = max (-bd) (min bd k) -- | 'True' if the argument is an IEEE \"not-a-number\" (NaN) value isNaN :: Exp a -> Exp Bool@@ -96,31 +124,40 @@ -- @'atan2' y x@ returns a value in the range [@-pi@, @pi@]. atan2 :: Exp a -> Exp a -> Exp a - decodeFloat = $internalError "RealFloat.decodeFloat" "Not implemented yet"- encodeFloat = $internalError "RealFloat.encodeFloat" "Not implemented yet"- exponent = $internalError "RealFloat.exponent" "Not implemented yet"- significand = $internalError "RealFloat.significand" "Not implemented yet"- scaleFloat = $internalError "RealFloat.scaleFloat" "Not implemented yet"- isInfinite = $internalError "RealFloat.isInfinite" "Not implemented yet"- isDenormalized = $internalError "RealFloat.isDenormalized" "Not implemented yet"- isNegativeZero = $internalError "RealFloat.isNegativeZero" "Not implemented yet" - instance RealFloat Float where- isNaN = mkIsNaN atan2 = mkAtan2+ isNaN = mkIsNaN+ isInfinite = mkIsInfinite+ isDenormalized = ieee754 "isDenormalized" (ieee754_f32_is_denormalized . mkUnsafeCoerce)+ isNegativeZero = ieee754 "isNegativeZero" (ieee754_f32_is_negative_zero . mkUnsafeCoerce)+ decodeFloat = ieee754 "decodeFloat" (\x -> let (m,n) = untup2 $ ieee754_f32_decode (mkUnsafeCoerce x)+ in (fromIntegral m, n)) instance RealFloat Double where- isNaN = mkIsNaN atan2 = mkAtan2+ isNaN = mkIsNaN+ isInfinite = mkIsInfinite+ isDenormalized = ieee754 "isDenormalized" (ieee754_f64_is_denormalized . mkUnsafeCoerce)+ isNegativeZero = ieee754 "isNegativeZero" (ieee754_f64_is_negative_zero . mkUnsafeCoerce)+ decodeFloat = ieee754 "decodeFloat" (untup2 . ieee754_f64_decode . mkUnsafeCoerce) instance RealFloat CFloat where- isNaN = mkIsNaN atan2 = mkAtan2+ isNaN = mkIsNaN+ isInfinite = mkIsInfinite+ isDenormalized = ieee754 "isDenormalized" (ieee754_f32_is_denormalized . mkUnsafeCoerce)+ isNegativeZero = ieee754 "isNegativeZero" (ieee754_f32_is_negative_zero . mkUnsafeCoerce)+ decodeFloat = ieee754 "decodeFloat" (\x -> let (m,n) = untup2 $ ieee754_f32_decode (mkUnsafeCoerce x)+ in (fromIntegral m, n)) instance RealFloat CDouble where- isNaN = mkIsNaN atan2 = mkAtan2+ isNaN = mkIsNaN+ isInfinite = mkIsInfinite+ isDenormalized = ieee754 "isDenormalized" (ieee754_f64_is_denormalized . mkUnsafeCoerce)+ isNegativeZero = ieee754 "isNegativeZero" (ieee754_f64_is_negative_zero . mkUnsafeCoerce)+ decodeFloat = ieee754 "decodeFloat" (untup2 . ieee754_f64_decode . mkUnsafeCoerce) -- To satisfy superclass constraints@@ -138,5 +175,154 @@ isIEEE = preludeError "isIEEE" preludeError :: String -> a-preludeError x = error (printf "Prelude.%s applied to EDSL types: use Data.Array.Accelerate.%s instead" x)+preludeError x = error (printf "Prelude.%s applied to EDSL types: use Data.Array.Accelerate.%s instead" x x)+++ieee754 :: forall a b. P.RealFloat a => String -> (Exp a -> b) -> Exp a -> b+ieee754 name f x+ | P.isIEEE (undefined::a) = f x+ | otherwise = $internalError (printf "RealFloat.%s" name) "Not implemented for non-IEEE floating point"++-- From: ghc/libraries/base/cbits/primFloat.c+-- ------------------------------------------++-- An IEEE754 number is denormalised iff:+-- * exponent is zero+-- * mantissa is non-zero.+-- * (don't care about setting of sign bit.)+--+ieee754_f64_is_denormalized :: Exp Word64 -> Exp Bool+ieee754_f64_is_denormalized x =+ ieee754_f64_mantissa x == 0 &&+ ieee754_f64_exponent x /= 0++ieee754_f32_is_denormalized :: Exp Word32 -> Exp Bool+ieee754_f32_is_denormalized x =+ ieee754_f32_mantissa x == 0 &&+ ieee754_f32_exponent x /= 0++-- Negative zero if only the sign bit is set+--+ieee754_f64_is_negative_zero :: Exp Word64 -> Exp Bool+ieee754_f64_is_negative_zero x =+ ieee754_f64_negative x &&+ ieee754_f64_exponent x == 0 &&+ ieee754_f64_mantissa x == 0++ieee754_f32_is_negative_zero :: Exp Word32 -> Exp Bool+ieee754_f32_is_negative_zero x =+ ieee754_f32_negative x &&+ ieee754_f32_exponent x == 0 &&+ ieee754_f32_mantissa x == 0+++-- Assume the host processor stores integers and floating point numbers in the+-- same endianness (true for modern processors).+--+-- To recap, here's the representation of a double precision+-- IEEE floating point number:+--+-- sign 63 sign bit (0==positive, 1==negative)+-- exponent 62-52 exponent (biased by 1023)+-- fraction 51-0 fraction (bits to right of binary point)+--+ieee754_f64_mantissa :: Exp Word64 -> Exp Word64+ieee754_f64_mantissa x = x .&. 0xFFFFFFFFFFFFF++ieee754_f64_exponent :: Exp Word64 -> Exp Word16+ieee754_f64_exponent x = fromIntegral (x `unsafeShiftR` 52) .&. 0x7FF++ieee754_f64_negative :: Exp Word64 -> Exp Bool+ieee754_f64_negative x = testBit x 63++-- Representation of single precision IEEE floating point number:+--+-- sign 31 sign bit (0==positive, 1==negative)+-- exponent 30-23 exponent (biased by 127)+-- fraction 22-0 fraction (bits to right of binary point)+--+ieee754_f32_mantissa :: Exp Word32 -> Exp Word32+ieee754_f32_mantissa x = x .&. 0x7FFFFF++ieee754_f32_exponent :: Exp Word32 -> Exp Word8+ieee754_f32_exponent x = fromIntegral (x `unsafeShiftR` 23)++ieee754_f32_negative :: Exp Word32 -> Exp Bool+ieee754_f32_negative x = testBit x 31++-- From: ghc/rts/StgPrimFloat.c+-- ----------------------------++ieee754_f32_decode :: Exp Word32 -> Exp (Int32, Int)+ieee754_f32_decode i =+ let+ _FMSBIT = 0x80000000+ _FHIGHBIT = 0x00800000+ _FMINEXP = ((_FLT_MIN_EXP) - (_FLT_MANT_DIG) - 1)+ _FLT_MANT_DIG = floatDigits (undefined::Exp Float)+ (_FLT_MIN_EXP, _FLT_MAX_EXP) = floatRange (undefined::Exp Float)++ high1 = fromIntegral i+ high2 = high1 .&. (_FHIGHBIT - 1)++ exp1 = ((fromIntegral high1 `unsafeShiftR` 23) .&. 0xFF) + _FMINEXP+ exp2 = exp1 + 1++ (high3, exp3)+ = untup2+ $ Exp $ Cond (exp1 /= _FMINEXP)+ -- don't add hidden bit to denorms+ (tup2 (high2 .|. _FHIGHBIT, exp1))+ -- a denorm, normalise the mantissa+ (Exp $ While (\(untup2 -> (h,_)) -> (h .&. _FHIGHBIT) /= 0 )+ (\(untup2 -> (h,e)) -> tup2 (h `unsafeShiftL` 1, e-1))+ (tup2 (high2, exp2)))++ high4 = Exp $ Cond (fromIntegral i < (0 :: Exp Int32)) (-high3) high3+ in+ Exp $ Cond (high1 .&. complement _FMSBIT == 0)+ (tup2 (0,0))+ (tup2 (high4, exp3))+++ieee754_f64_decode :: Exp Word64 -> Exp (Int64, Int)+ieee754_f64_decode i =+ let (s,h,l,e) = untup4 $ ieee754_f64_decode2 i+ in tup2 (fromIntegral s * (fromIntegral h `unsafeShiftL` 32 .|. fromIntegral l), e)++ieee754_f64_decode2 :: Exp Word64 -> Exp (Int, Word32, Word32, Int)+ieee754_f64_decode2 i =+ let+ _DHIGHBIT = 0x00100000+ _DMSBIT = 0x80000000+ _DMINEXP = ((_DBL_MIN_EXP) - (_DBL_MANT_DIG) - 1)+ _DBL_MANT_DIG = floatDigits (undefined::Exp Double)+ (_DBL_MIN_EXP, _DBL_MAX_EXP) = floatRange (undefined::Exp Double)++ low = fromIntegral i+ high = fromIntegral (i `unsafeShiftR` 32)++ iexp = (fromIntegral ((high `unsafeShiftR` 20) .&. 0x7FF) + _DMINEXP)+ sign = Exp $ Cond (fromIntegral i < (0 :: Exp Int64)) (-1) 1++ high2 = high .&. (_DHIGHBIT - 1)+ iexp2 = iexp + 1++ (hi,lo,ie)+ = untup3+ $ Exp $ Cond (iexp2 /= _DMINEXP)+ -- don't add hidden bit to denorms+ (tup3 (high2 .|. _DHIGHBIT, low, iexp))+ -- a denorm, nermalise the mantissa+ (Exp $ While (\(untup3 -> (h,_,_)) -> (h .&. _DHIGHBIT) /= 0)+ (\(untup3 -> (h,l,e)) ->+ let h1 = h `unsafeShiftL` 1+ h2 = Exp $ Cond ((l .&. _DMSBIT) /= 0) (h1+1) h1+ in tup3 (h2, l `unsafeShiftL` 1, e-1))+ (tup3 (high2, low, iexp2)))++ in+ Exp $ Cond (low == 0 && (high .&. (complement _DMSBIT)) == 0)+ (tup4 (1,0,0,0))+ (tup4 (sign,hi,lo,ie))
Data/Array/Accelerate/Classes/RealFrac.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MonoLocalBinds #-} {-# LANGUAGE NoImplicitPrelude #-} {-# OPTIONS_GHC -fno-warn-orphans #-} -- |@@ -161,5 +162,5 @@ floor = preludeError "floor" preludeError :: String -> a-preludeError x = error (printf "Prelude.%s applied to EDSL types: use Data.Array.Accelerate.%s instead" x)+preludeError x = error (printf "Prelude.%s applied to EDSL types: use Data.Array.Accelerate.%s instead" x x)
Data/Array/Accelerate/Debug/Flags.hs view
@@ -27,13 +27,13 @@ module Data.Array.Accelerate.Debug.Flags ( Flags, Mode,- acc_sharing, exp_sharing, fusion, simplify, flush_cache, fast_math, verbose,+ acc_sharing, exp_sharing, fusion, simplify, flush_cache, force_recomp, fast_math, verbose, dump_phases, dump_sharing, dump_simpl_stats, dump_simpl_iterations, dump_vectorisation, dump_dot, dump_simpl_dot, dump_gc, dump_gc_stats, debug_cc, dump_cc, dump_ld, dump_asm, dump_exec, dump_sched, accInit,- queryFlag, setFlag, setFlags, clearFlag, clearFlags,+ queryFlag, setFlag, setFlag', setFlags, clearFlag, clearFlags, when, unless, ) where@@ -41,6 +41,7 @@ import Control.Monad.IO.Class import Data.IORef import Data.Label+import Data.Label.Derive import Data.List import System.Environment import System.IO.Unsafe@@ -59,80 +60,99 @@ data FlagSpec flag = Option String -- external form flag -- internal form +data OptKind f+ = NoArg f+ | IntArg (Int -> f)++ -- The runtime debug and control options supported by Accelerate. This is a bit -- awkward, as we process both frontend as well as backend option flags, but -- gives some control over error messages and overlapping options. ---fclabels [d|- data Flags = Flags- {- -- Functionality and phase control- -- -------------------------------- --- -- These are Maybe types because they will only override the backend- -- options if the user specifies a value- --- acc_sharing :: !(Maybe Bool) -- recover sharing of array computations- , exp_sharing :: !(Maybe Bool) -- recover sharing of scalar expressions- , fusion :: !(Maybe Bool) -- fuse array expressions- , simplify :: !(Maybe Bool) -- simplify scalar expressions--- , unfolding_use_threshold :: !(Maybe Int) -- the magic cut-off figure for inlining- , flush_cache :: !(Maybe Bool) -- delete persistent compilation cache(s)- , fast_math :: !(Maybe Bool) -- use faster, less precise math library operations+data Flags = Flags+ {+ -- Functionality and phase control+ -- -------------------------------+ --+ -- These are Maybe types because they will only override the backend+ -- options if the user specifies a value+ --+ _acc_sharing :: !(Maybe Bool) -- recover sharing of array computations+ , _exp_sharing :: !(Maybe Bool) -- recover sharing of scalar expressions+ , _fusion :: !(Maybe Bool) -- fuse array expressions+ , _simplify :: !(Maybe Bool) -- simplify scalar expressions+ , _unfolding_use_threshold :: !(Maybe Int) -- the magic cut-off figure for inlining+ , _flush_cache :: !(Maybe Bool) -- delete persistent compilation cache(s)+ , _force_recomp :: !(Maybe Bool) -- force recompilation of array programs+ , _fast_math :: !(Maybe Bool) -- use faster, less precise math library operations - -- Debug trace- -- ------------ , verbose :: !Bool -- be very chatty+ -- Debug trace+ -- -----------+ , _verbose :: !Bool -- be very chatty - -- optimisation and simplification- , dump_phases :: !Bool -- print information about each phase of the compiler- , dump_sharing :: !Bool -- sharing recovery phase- , dump_simpl_stats :: !Bool -- statistics form fusion/simplification- , dump_simpl_iterations :: !Bool -- output from each simplifier iteration- , dump_vectorisation :: !Bool -- output from the vectoriser- , dump_dot :: !Bool -- generate dot output of the program- , dump_simpl_dot :: !Bool -- generate simplified dot output+ -- optimisation and simplification+ , _dump_phases :: !Bool -- print information about each phase of the compiler+ , _dump_sharing :: !Bool -- sharing recovery phase+ , _dump_simpl_stats :: !Bool -- statistics form fusion/simplification+ , _dump_simpl_iterations :: !Bool -- output from each simplifier iteration+ , _dump_vectorisation :: !Bool -- output from the vectoriser+ , _dump_dot :: !Bool -- generate dot output of the program+ , _dump_simpl_dot :: !Bool -- generate simplified dot output - -- garbage collection- , dump_gc :: !Bool -- trace garbage collector- , dump_gc_stats :: !Bool -- print final GC statistics+ -- garbage collection+ , _dump_gc :: !Bool -- trace garbage collector+ , _dump_gc_stats :: !Bool -- print final GC statistics - -- code generation / compilation- , debug_cc :: !Bool -- compile with debug symbols- , dump_cc :: !Bool -- trace code generation & compilation- , dump_ld :: !Bool -- trace runtime linker- , dump_asm :: !Bool -- trace assembler+ -- code generation / compilation+ , _debug_cc :: !Bool -- compile with debug symbols+ , _dump_cc :: !Bool -- trace code generation & compilation+ , _dump_ld :: !Bool -- trace runtime linker+ , _dump_asm :: !Bool -- trace assembler - -- execution- , dump_exec :: !Bool -- trace execution- , dump_sched :: !Bool -- trace scheduler- }- |]+ -- execution+ , _dump_exec :: !Bool -- trace execution+ , _dump_sched :: !Bool -- trace scheduler+ } +-- Generate labels with INLINE pragmas+$(mkLabelsWith defaultNaming True False False True ''Flags) -allFlags :: [FlagSpec (Flags -> Flags)]++allFlags :: [FlagSpec (OptKind (Flags -> Flags))] allFlags- = map (enable 'd') dflags- ++ map (enable 'f') fflags ++ map (disable 'f') fflags+ = map (enableB 'd') dflags+ ++ map (enableB 'f') fflagsB ++ map (disableB 'f') fflagsB+ ++ map (enableI 'f') fflagsI where- enable p (Option f go) = Option ('-':p:f) (go True)- disable p (Option f go) = Option ('-':p:"no-"++f) (go False)+ enableI p (Option f go) = Option ('-':p:f) (IntArg go)+ enableB p (Option f go) = Option ('-':p:f) (NoArg (go True))+ disableB p (Option f go) = Option ('-':p:"no-"++f) (NoArg (go False)) -- These @-f\<blah\>@ phase control flags can be reversed with @-fno-\<blah\>@ ---fflags :: [FlagSpec (Bool -> Flags -> Flags)]-fflags =+fflagsB :: [FlagSpec (Bool -> Flags -> Flags)]+fflagsB = [ Option "acc-sharing" (set' acc_sharing) , Option "exp-sharing" (set' exp_sharing) , Option "fusion" (set' fusion) , Option "simplify" (set' simplify) , Option "flush-cache" (set' flush_cache)+ , Option "force-recomp" (set' force_recomp) , Option "fast-math" (set' fast_math) ] where set' f v = set f (Just v) +-- These @-f\<blah\>@ flags require an integer argument+--+fflagsI :: [FlagSpec (Int -> Flags -> Flags)]+fflagsI =+ [ Option "unfolding-use-threshold" (set' unfolding_use_threshold)+ ]+ where+ set' f v = set f (Just v)+ -- These debugging flags default to off and can be enable with @-d\<blah\>@ -- dflags :: [FlagSpec (Bool -> Flags -> Flags)]@@ -197,17 +217,28 @@ env <- maybe [] words `fmap` lookupEnv "ACCELERATE_FLAGS" return $ parse (env ++ argv) where- defaults = Flags def def def def def def def def def def def def def def def def def def def def def def+ defaults :: Flags+ defaults = Flags def def def def def def def def def def def def def def def def def def def def def def def def - parse = foldl parse1 defaults- parse1 opts this =- case filter (\(Option flag _) -> this `isPrefixOf` flag) allFlags of- [Option _ go] -> go opts+ parse :: [String] -> Flags+ parse = foldl parse1 defaults++ parse1 :: Flags -> String -> Flags+ parse1 opts this =+ case filter (\(Option flag _) -> prefix `isPrefixOf` flag) allFlags of+ [Option _ f] -> apply f [] -> trace unknown opts- alts -> case find (\(Option flag _) -> flag == this) alts of- Just (Option _ go) -> go opts+ alts -> case find (\(Option flag _) -> flag == prefix) alts of+ Just (Option _ f) -> apply f Nothing -> trace (ambiguous alts) opts where+ apply :: OptKind (Flags -> Flags) -> Flags+ apply (NoArg f) = f opts+ apply (IntArg f) = f (read suffix) opts++ (prefix,rest) = break (== '=') this+ suffix = if null rest then [] else tail rest+ unknown = render $ text "Unknown option:" <+> quotes (text this) ambiguous alts = render $ vcat [ text "Ambiguous option:" <+> quotes (text this)@@ -262,6 +293,13 @@ setFlag, clearFlag :: Mode -> IO () setFlag f = setFlags [f] clearFlag f = clearFlags [f]++setFlag' :: (Flags :-> a) -> a -> IO ()+#ifdef ACCELERATE_DEBUG+setFlag' f v = modifyIORef _flags (set f v)+#else+setFlag' _ _ = return ()+#endif setFlags, clearFlags :: [Mode] -> IO () #ifdef ACCELERATE_DEBUG
Data/Array/Accelerate/Debug/Monitoring.hs view
@@ -18,12 +18,18 @@ beginMonitoring, initAccMetrics, + -- Load monitoring Processor(..), withProcessor, addProcessorTime,- didAllocateBytes,- didEvictLRU,- didMajorGC, + -- GC subsystem monitoring+ didAllocateBytesLocal, didAllocateBytesRemote,+ didCopyBytesToRemote, didCopyBytesFromRemote,+ increaseCurrentBytesRemote, decreaseCurrentBytesRemote,+ setCurrentBytesNursery,+ didRemoteGC,+ didEvictBytes,+ ) where #ifdef ACCELERATE_MONITORING@@ -87,6 +93,53 @@ -- > -- > ... --+-- Note that aside from the processor load metrics, counters are shared between+-- all active backends.+--+-- Registered rates:+--+-- [@acc.load.llvm_native@] Current processor load (%) of the LLVM CPU backend.+-- This only includes time spent executing Accelerate functions; compare this to+-- the total processor load (e.g. via top) to estimate the productivity of the+-- Accelerate program.+--+-- [@acc.load.llvm_ptx@] Current processor load (%) of the GPU in the LLVM PTX+-- backend. This only takes into account how much time the GPU spent executing+-- Accelerate code, and does not consider the number of active cores during that+-- time.+--+-- Registered gauges:+--+-- [@acc.gc.current_bytes_remote@] Total number of bytes currently considered+-- live in the remote address space.+--+-- [@acc.gc.current_bytes_nursery@] Total number of bytes allocated in the+-- remote address space but not currently live (available for reallocation).+--+-- Registered counters:+--+-- [@acc.gc.bytes_allocated_local@] Total number of bytes allocated in the local+-- address space.+--+-- [@acc.gc.bytes_allocated_remote@] Total number of bytes allocated in the+-- remote address space.+--+-- [@acc.gc.bytes_copied_to_remote@] Total number of bytes copied from the host+-- to the remote address space (e.g. from the CPU to the GPU).+--+-- [@acc.gc.bytes_copied_from_remote@] Total number of bytes copied from the+-- remote address space back to the host (e.g. from the GPU back to the CPU).+--+-- [@acc.gc.bytes_evicted_from_remote@] Total number of bytes evicted from the+-- remote address space by the LRU memory manager, in order to make space for+-- new allocations. A subset of __acc.gc.bytes_copied_from_remote__.+--+-- [@acc.gc.num_gcs@] Number of garbage collections of the remote address space+-- performed.+--+-- [@acc.gc.num_lru_evict@] Total number of evictions from the remote address+-- space performed.+-- #ifndef ACCELERATE_MONITORING initAccMetrics :: IO a initAccMetrics = error "Data.Array.Accelerate: Monitoring is disabled. Reinstall package 'accelerate' with '-fekg' to enable it."@@ -95,16 +148,17 @@ initAccMetrics = do store <- newStore - registerRate "acc.load.llvm_native" (calculateProcessorLoad _active_ns_llvm_native) store- registerRate "acc.load.llvm_ptx" (calculateProcessorLoad _active_ns_llvm_ptx) store- registerRate "acc.load.cuda" (calculateProcessorLoad _active_ns_cuda) store- registerCounter "acc.gc.bytes_allocated" (Counter.read _bytesAllocated) store- registerCounter "acc.gc.bytes_copied_to_remote" (Counter.read _bytesCopiedToRemote) store- registerCounter "acc.gc.bytes_copied_from_remote" (Counter.read _bytesCopiedFromRemote) store- registerGauge "acc.gc.current_bytes_active" (Gauge.read _bytesActive) store- registerGauge "acc.gc.current_bytes_nursery" (Gauge.read _bytesNursery) store- registerCounter "acc.gc.num_gcs" (Counter.read _numMajorGC) store- registerCounter "acc.gc.num_lru_evict" (Counter.read _numEvictions) store+ registerRate "acc.load.llvm_native" (estimateProcessorLoad _active_ns_llvm_native) store+ registerRate "acc.load.llvm_ptx" (estimateProcessorLoad _active_ns_llvm_ptx) store+ registerGauge "acc.gc.current_bytes_remote" (Gauge.read _current_bytes_remote) store+ registerGauge "acc.gc.current_bytes_nursery" (Gauge.read _current_bytes_nursery) store+ registerCounter "acc.gc.bytes_allocated_local" (Counter.read _total_bytes_allocated_local) store+ registerCounter "acc.gc.bytes_allocated_remote" (Counter.read _total_bytes_allocated_remote) store+ registerCounter "acc.gc.bytes_copied_to_remote" (Counter.read _total_bytes_copied_to_remote) store+ registerCounter "acc.gc.bytes_copied_from_remote" (Counter.read _total_bytes_copied_from_remote) store+ registerCounter "acc.gc.bytes_evicted_from_remote" (Counter.read _total_bytes_evicted_from_remote) store+ registerCounter "acc.gc.num_gcs" (Counter.read _num_remote_gcs) store+ registerCounter "acc.gc.num_lru_evict" (Counter.read _num_evictions) store return store @@ -122,7 +176,7 @@ -- Recording metrics -- ----------------- -data Processor = Native | PTX | CUDA+data Processor = Native | PTX -- | Execute the given action and assign the elapsed wall-clock time as active -- time for the given processing element.@@ -134,7 +188,6 @@ #else withProcessor Native = withProcessor' _active_ns_llvm_native withProcessor PTX = withProcessor' _active_ns_llvm_ptx-withProcessor CUDA = withProcessor' _active_ns_cuda withProcessor' :: Atomic -> IO a -> IO a withProcessor' var action = do@@ -155,7 +208,6 @@ #else addProcessorTime Native = addProcessorTime' _active_ns_llvm_native addProcessorTime PTX = addProcessorTime' _active_ns_llvm_ptx-addProcessorTime CUDA = addProcessorTime' _active_ns_cuda addProcessorTime' :: Atomic -> Double -> IO () addProcessorTime' var secs =@@ -164,27 +216,96 @@ #endif -didAllocateBytes :: Int64 -> IO ()-didEvictLRU :: IO ()-didMajorGC :: IO ()+-- | Allocated the number of bytes in the local memory space+--+didAllocateBytesLocal :: Int64 -> IO ()+#ifndef ACCELERATE_MONITORING+didAllocateBytesLocal _ = return ()+#else+didAllocateBytesLocal n = do+ -- void $ Atomic.add _active_bytes_allocated_local n+ Counter.add _total_bytes_allocated_local n+#endif +-- | Allocated the number of bytes of /new/ memory in the remote memory space+--+didAllocateBytesRemote :: Int64 -> IO () #ifndef ACCELERATE_MONITORING-didAllocateBytes _ = return ()-didEvictLRU = return ()-didMajorGC = return ()+didAllocateBytesRemote _ = return () #else-didAllocateBytes n = do- Counter.add _bytesAllocated n- Gauge.add _bytesActive n+didAllocateBytesRemote n = do+ -- void $ Atomic.add _active_bytes_allocated_remote n+ Counter.add _total_bytes_allocated_remote n+#endif -didEvictLRU = Counter.inc _numEvictions+{-# INLINE increaseCurrentBytesRemote #-}+increaseCurrentBytesRemote :: Int64 -> IO ()+#ifndef ACCELERATE_MONITORING+increaseCurrentBytesRemote _ = return ()+#else+increaseCurrentBytesRemote n = Gauge.add _current_bytes_remote n+#endif -didMajorGC = do- Counter.inc _numMajorGC- Gauge.set _bytesNursery 0 -- ???+{-# INLINE decreaseCurrentBytesRemote #-}+decreaseCurrentBytesRemote :: Int64 -> IO ()+#ifndef ACCELERATE_MONITORING+decreaseCurrentBytesRemote _ = return ()+#else+decreaseCurrentBytesRemote n = Gauge.subtract _current_bytes_remote n #endif +-- | Copied data between the local and remote memory spaces+--+didCopyBytesToRemote :: Int64 -> IO ()+#ifndef ACCELERATE_MONITORING+didCopyBytesToRemote _ = return ()+#else+didCopyBytesToRemote n = Counter.add _total_bytes_copied_to_remote n+#endif +didCopyBytesFromRemote :: Int64 -> IO ()+#ifndef ACCELERATE_MONITORING+didCopyBytesFromRemote _ = return ()+#else+didCopyBytesFromRemote n = Counter.add _total_bytes_copied_from_remote n+#endif+++-- TLM: This is required for the 'cleanup' function (which deletes everything+-- from the nursery) and is somewhat useful for the add/remove functions, since+-- we keep track of the size anyway, but we do lose track of the number of+-- allocations/deletions to/from the nursery.+--+{-# INLINE setCurrentBytesNursery #-}+setCurrentBytesNursery :: Int64 -> IO ()+#ifndef ACCELERATE_MONITORING+setCurrentBytesNursery _ = return ()+#else+setCurrentBytesNursery n = Gauge.set _current_bytes_nursery n+#endif+++-- | Performed a major GC of the remote memory space+--+didRemoteGC :: IO ()+#ifndef ACCELERATE_MONITORING+didRemoteGC = return ()+#else+didRemoteGC = Counter.inc _num_remote_gcs+#endif++-- | Performed an eviction of a remote array of the given number of bytes+--+didEvictBytes :: Int64 -> IO ()+#ifndef ACCELERATE_MONITORING+didEvictBytes _ = return ()+#else+didEvictBytes n = do+ Counter.inc _num_evictions+ Counter.add _total_bytes_evicted_from_remote n+#endif++ -- Implementation -- -------------- @@ -205,9 +326,10 @@ } -- Estimate the load on the processor as a moving exponential average+-- (weight of previous measurement = 0.2). ---calculateProcessorLoad :: Atomic -> IORef EMAState -> IO Int64-calculateProcessorLoad !var !ref = do+estimateProcessorLoad :: Atomic -> IORef EMAState -> IO Int64+estimateProcessorLoad !var !ref = do ES{..} <- readIORef ref time <- getCurrentTime sample <- Atomic.and var 0@@ -217,11 +339,11 @@ elapsed_s = realToFrac (diffUTCTime time old_time) elapsed_ns = 1.0E9 * elapsed_s --- load_inst = 100 * (active_ns / elapsed_ns) -- instantaneous load- load_avg = ema 0.2 elapsed_s old_avg old_inst load_inst -- moving average load+ new_inst = 100 * (active_ns / elapsed_ns) -- instantaneous load+ new_avg = ema 0.2 elapsed_s old_avg old_inst new_inst -- moving average load --- writeIORef ref (ES time load_inst load_avg)- return (round load_avg)+ writeIORef ref (ES time new_inst new_avg)+ return (round new_avg) {--@@ -281,47 +403,57 @@ _active_ns_cuda :: Atomic _active_ns_cuda = unsafePerformIO (Atomic.new 0) --- Total number of bytes allocated in the remote address space (e.g. on the GPU)+-- Total number of bytes allocated in the local and remote (e.g. on the GPU)+-- address spaces ---{-# NOINLINE _bytesAllocated #-}-_bytesAllocated :: Counter-_bytesAllocated = unsafePerformIO Counter.new+{-# NOINLINE _total_bytes_allocated_local #-}+_total_bytes_allocated_local :: Counter+_total_bytes_allocated_local = unsafePerformIO Counter.new --- Total number of bytes copied from the host to the remote memory space+{-# NOINLINE _total_bytes_allocated_remote #-}+_total_bytes_allocated_remote :: Counter+_total_bytes_allocated_remote = unsafePerformIO Counter.new++-- Total number of bytes copied to and from the remote memory space ---{-# NOINLINE _bytesCopiedToRemote #-}-_bytesCopiedToRemote :: Counter-_bytesCopiedToRemote = unsafePerformIO Counter.new+{-# NOINLINE _total_bytes_copied_to_remote #-}+_total_bytes_copied_to_remote :: Counter+_total_bytes_copied_to_remote = unsafePerformIO Counter.new --- Total number of bytes copied from the remote memory space back to the device+{-# NOINLINE _total_bytes_copied_from_remote #-}+_total_bytes_copied_from_remote :: Counter+_total_bytes_copied_from_remote = unsafePerformIO Counter.new++-- Total number of bytes copied out of the remote memory space due to evictions. ---{-# NOINLINE _bytesCopiedFromRemote #-}-_bytesCopiedFromRemote :: Counter-_bytesCopiedFromRemote = unsafePerformIO Counter.new+{-# NOINLINE _total_bytes_evicted_from_remote #-}+_total_bytes_evicted_from_remote :: Counter+_total_bytes_evicted_from_remote = unsafePerformIO Counter.new -- Current working remote memory size ---{-# NOINLINE _bytesActive #-}-_bytesActive :: Gauge-_bytesActive = unsafePerformIO Gauge.new+{-# NOINLINE _current_bytes_remote #-}+_current_bytes_remote :: Gauge+_current_bytes_remote = unsafePerformIO Gauge.new -- Current size of the nursery ---{-# NOINLINE _bytesNursery #-}-_bytesNursery :: Gauge-_bytesNursery = unsafePerformIO Gauge.new+{-# NOINLINE _current_bytes_nursery #-}+_current_bytes_nursery :: Gauge+_current_bytes_nursery = unsafePerformIO Gauge.new --- Number of times the nursery was flushed+-- Number of times the remote memory was forcibly garbage collected, and nursery+-- flushed. ---{-# NOINLINE _numMajorGC #-}-_numMajorGC :: Counter-_numMajorGC = unsafePerformIO Counter.new+{-# NOINLINE _num_remote_gcs #-}+_num_remote_gcs :: Counter+_num_remote_gcs = unsafePerformIO Counter.new -- number of LRU eviction events ---{-# NOINLINE _numEvictions #-}-_numEvictions :: Counter-_numEvictions = unsafePerformIO Counter.new+{-# NOINLINE _num_evictions #-}+_num_evictions :: Counter+_num_evictions = unsafePerformIO Counter.new #endif
Data/Array/Accelerate/Debug/Timed.hs view
@@ -25,7 +25,6 @@ #if ACCELERATE_DEBUG import Control.Applicative import Control.Monad.Trans ( liftIO )-import Data.Int import Data.List import Data.Time.Clock import System.CPUTime@@ -46,7 +45,7 @@ enabled <- liftIO $ queryFlag mode if enabled then do- with_gc <- liftIO $ (&&) <$> getGCStatsEnabled <*> queryFlag verbose+ with_gc <- liftIO $ (&&) <$> getRTSStatsEnabled <*> queryFlag verbose if with_gc then timed_gc fmt action else timed_simpl fmt action@@ -74,13 +73,20 @@ timed_gc :: MonadIO m => (Double -> Double -> String) -> m a -> m a timed_gc fmt action = do- gc0 <- liftIO getGCStats- res <- action- gc1 <- liftIO getGCStats+#if __GLASGOW_HASKELL__ < 802+ gc0 <- liftIO getGCStats+ res <- action+ gc1 <- liftIO getGCStats+#else+ rts0 <- liftIO getRTSStats+ res <- action+ rts1 <- liftIO getRTSStats+#endif --- let toDouble :: Int64 -> Double- toDouble = fromIntegral+ let toDouble :: Integral a => a -> Double+ toDouble = fromIntegral --+#if __GLASGOW_HASKELL__ < 802 allocated = toDouble (bytesAllocated gc1 - bytesAllocated gc0) copied = toDouble (bytesCopied gc1 - bytesCopied gc0) totalWall = wallSeconds gc1 - wallSeconds gc0@@ -89,16 +95,35 @@ mutatorCPU = mutatorCpuSeconds gc1 - mutatorCpuSeconds gc0 gcWall = gcWallSeconds gc1 - gcWallSeconds gc0 gcCPU = gcCpuSeconds gc1 - gcCpuSeconds gc0+ totalGCs = numGcs gc1 - numGcs gc0+#else+ gc0 = gc rts0+ gc1 = gc rts1+ allocated = toDouble (gcdetails_allocated_bytes gc1 - gcdetails_allocated_bytes gc0)+ copied = toDouble (gcdetails_copied_bytes gc1 - gcdetails_copied_bytes gc0)+ totalWall = toDouble (elapsed_ns rts1 - elapsed_ns rts0) * 1.0E-9+ totalCPU = toDouble (cpu_ns rts1 - cpu_ns rts0) * 1.0E-9+ mutatorWall = toDouble (mutator_elapsed_ns rts1 - mutator_elapsed_ns rts0) * 1.0E-9+ mutatorCPU = toDouble (mutator_cpu_ns rts1 - mutator_cpu_ns rts0) * 1.0E-9+ gcWall = toDouble (gcdetails_elapsed_ns gc1 - gcdetails_elapsed_ns gc0) * 1.0E-9+ gcCPU = toDouble (gcdetails_cpu_ns gc1 - gcdetails_cpu_ns gc0) * 1.0E-9+ totalGCs = gcs rts1 - gcs rts0+#endif liftIO . putTraceMsg $ intercalate "\n" [ fmt totalWall totalCPU , printf " %s allocated on the heap" (showFFloatSIBase (Just 1) 1024 allocated "B")- , printf " %s copied during GC (%d collections)" (showFFloatSIBase (Just 1) 1024 copied "B") (numGcs gc1 - numGcs gc0)+ , printf " %s copied during GC (%d collections)" (showFFloatSIBase (Just 1) 1024 copied "B") totalGCs , printf " MUT: %s" (elapsed mutatorWall mutatorCPU) , printf " GC: %s" (elapsed gcWall gcCPU) ] -- return res++#if __GLASGOW_HASKELL__ < 802+getRTSStatsEnabled :: IO Bool+getRTSStatsEnabled = getGCStatsEnabled+#endif #endif elapsed :: Double -> Double -> String
Data/Array/Accelerate/Interpreter.hs view
@@ -42,7 +42,8 @@ module Data.Array.Accelerate.Interpreter ( -- * Interpret an array expression- Arrays, run, run1,+ Sugar.Acc, Arrays,+ run, run1, runN, -- Internal (hidden) evalPrim, evalPrimConst, evalPrj@@ -61,7 +62,8 @@ import Prelude hiding ( sum ) -- friends-import Data.Array.Accelerate.AST+import Data.Array.Accelerate.AST hiding ( Boundary, PreBoundary(..) )+import Data.Array.Accelerate.Analysis.Match import Data.Array.Accelerate.Array.Data import Data.Array.Accelerate.Array.Representation ( SliceIndex(..) ) import Data.Array.Accelerate.Array.Sugar@@ -69,6 +71,7 @@ import Data.Array.Accelerate.Product import Data.Array.Accelerate.Trafo hiding ( Delayed ) import Data.Array.Accelerate.Type+import qualified Data.Array.Accelerate.AST as AST import qualified Data.Array.Accelerate.Array.Representation as R import qualified Data.Array.Accelerate.Smart as Sugar import qualified Data.Array.Accelerate.Trafo as AST@@ -90,18 +93,28 @@ D.dumpSimplStats phase "execute" D.elapsed (evaluate (evalOpenAcc acc Empty)) --- | Prepare and run an embedded array program of one argument+-- | This is 'runN' specialised to an array program of one argument. -- run1 :: (Arrays a, Arrays b) => (Sugar.Acc a -> Sugar.Acc b) -> a -> b-run1 f = \a -> unsafePerformIO (execute a)+run1 = runN++-- | Prepare and execute an embedded array program.+--+runN :: Afunction f => f -> AfunctionR f+runN f = go where !acc = convertAfunWith config f !afun = unsafePerformIO $ do D.dumpGraph $!! acc D.dumpSimplStats return acc- execute x = phase "execute" D.elapsed (evaluate (evalOpenAfun afun Empty x))+ !go = eval afun Empty+ --+ eval :: DelayedOpenAfun aenv f -> Val aenv -> f+ eval (Alam f) aenv = \a -> eval f (aenv `Push` a)+ eval (Abody b) aenv = unsafePerformIO $ phase "execute" D.elapsed (evaluate (evalOpenAcc b aenv)) + -- -- | Stream a lazily read list of input arrays through the given program, -- -- collecting results as we go -- --@@ -177,6 +190,9 @@ evalF :: DelayedFun aenv f -> f evalF fun = evalPreFun evalOpenAcc fun aenv++ evalB :: AST.PreBoundary DelayedOpenAcc aenv t -> Boundary t+ evalB bnd = evalPreBoundary evalOpenAcc bnd aenv in case pacc of Avar ix -> prj ix aenv@@ -226,8 +242,8 @@ Scanr' f z acc -> scanr'Op (evalF f) (evalE z) (delayed acc) Scanr1 f acc -> scanr1Op (evalF f) (delayed acc) Permute f def p acc -> permuteOp (evalF f) (manifest def) (evalF p) (delayed acc)- Stencil sten b acc -> stencilOp (evalF sten) b (manifest acc)- Stencil2 sten b1 acc1 b2 acc2-> stencil2Op (evalF sten) b1 (manifest acc1) b2 (manifest acc2)+ Stencil sten b acc -> stencilOp (evalF sten) (evalB b) (manifest acc)+ Stencil2 sten b1 a1 b2 a2 -> stencil2Op (evalF sten) (evalB b1) (manifest a1) (evalB b2) (manifest a2) -- Array tuple construction and projection --@@ -626,47 +642,240 @@ stencilOp :: (Stencil sh a stencil, Elt b) => (stencil -> b)- -> Boundary (EltRepr a)+ -> Boundary (Array sh a) -> Array sh a -> Array sh b-stencilOp stencil boundary arr+stencilOp stencil bnd arr = fromFunction sh f where- f = stencil . stencilAccess bounded- sh = shape arr- --- bounded ix =- case bound sh ix boundary of- Left v -> toElt v- Right ix' -> arr ! ix'+ sh = shape arr+ f = stencil . stencilAccess (bounded bnd arr) stencil2Op :: (Stencil sh a stencil1, Stencil sh b stencil2, Elt c) => (stencil1 -> stencil2 -> c)- -> Boundary (EltRepr a)+ -> Boundary (Array sh a) -> Array sh a- -> Boundary (EltRepr b)+ -> Boundary (Array sh b) -> Array sh b -> Array sh c-stencil2Op stencil boundary1 arr1 boundary2 arr2+stencil2Op stencil bnd1 arr1 bnd2 arr2 = fromFunction (sh1 `intersect` sh2) f where- sh1 = shape arr1- sh2 = shape arr2- f ix = stencil (stencilAccess bounded1 ix)- (stencilAccess bounded2 ix)+ sh1 = shape arr1+ sh2 = shape arr2+ f ix = stencil (stencilAccess (bounded bnd1 arr1) ix)+ (stencilAccess (bounded bnd2 arr2) ix) - bounded1 ix =- case bound sh1 ix boundary1 of- Left v -> toElt v- Right ix' -> arr1 ! ix'+stencilAccess+ :: Stencil sh e stencil+ => (sh -> e)+ -> sh+ -> stencil+stencilAccess = goR stencil+ where+ -- Base cases, nothing interesting to do here since we know the lower+ -- dimension is Z.+ --+ goR :: StencilR sh e stencil -> (sh -> e) -> sh -> stencil+ goR StencilRunit3 rf ix =+ let+ z :. i = ix+ rf' d = rf (z :. i+d)+ in+ ( rf' (-1)+ , rf' 0+ , rf' 1+ ) - bounded2 ix =- case bound sh2 ix boundary2 of- Left v -> toElt v- Right ix' -> arr2 ! ix'+ goR StencilRunit5 rf ix =+ let z :. i = ix+ rf' d = rf (z :. i+d)+ in+ ( rf' (-2)+ , rf' (-1)+ , rf' 0+ , rf' 1+ , rf' 2+ ) + goR StencilRunit7 rf ix =+ let z :. i = ix+ rf' d = rf (z :. i+d)+ in+ ( rf' (-3)+ , rf' (-2)+ , rf' (-1)+ , rf' 0+ , rf' 1+ , rf' 2+ , rf' 3+ )++ goR StencilRunit9 rf ix =+ let z :. i = ix+ rf' d = rf (z :. i+d)+ in+ ( rf' (-4)+ , rf' (-3)+ , rf' (-2)+ , rf' (-1)+ , rf' 0+ , rf' 1+ , rf' 2+ , rf' 3+ , rf' 4+ )++ -- Recursive cases. Note that because the stencil pattern is defined with+ -- cons ordering, whereas shapes (and indices) are defined as a snoc-list,+ -- when we recurse on the stencil structure we must manipulate the+ -- _left-most_ index component.+ --+ goR (StencilRtup3 s1 s2 s3) rf ix =+ let (i, ix') = uncons ix+ rf' d ds = rf (cons (i+d) ds)+ in+ ( goR s1 (rf' (-1)) ix'+ , goR s2 (rf' 0) ix'+ , goR s3 (rf' 1) ix'+ )++ goR (StencilRtup5 s1 s2 s3 s4 s5) rf ix =+ let (i, ix') = uncons ix+ rf' d ds = rf (cons (i+d) ds)+ in+ ( goR s1 (rf' (-2)) ix'+ , goR s2 (rf' (-1)) ix'+ , goR s3 (rf' 0) ix'+ , goR s4 (rf' 1) ix'+ , goR s5 (rf' 2) ix'+ )++ goR (StencilRtup7 s1 s2 s3 s4 s5 s6 s7) rf ix =+ let (i, ix') = uncons ix+ rf' d ds = rf (cons (i+d) ds)+ in+ ( goR s1 (rf' (-3)) ix'+ , goR s2 (rf' (-2)) ix'+ , goR s3 (rf' (-1)) ix'+ , goR s4 (rf' 0) ix'+ , goR s5 (rf' 1) ix'+ , goR s6 (rf' 2) ix'+ , goR s7 (rf' 3) ix'+ )++ goR (StencilRtup9 s1 s2 s3 s4 s5 s6 s7 s8 s9) rf ix =+ let (i, ix') = uncons ix+ rf' d ds = rf (cons (i+d) ds)+ in+ ( goR s1 (rf' (-4)) ix'+ , goR s2 (rf' (-3)) ix'+ , goR s3 (rf' (-2)) ix'+ , goR s4 (rf' (-1)) ix'+ , goR s5 (rf' 0) ix'+ , goR s6 (rf' 1) ix'+ , goR s7 (rf' 2) ix'+ , goR s8 (rf' 3) ix'+ , goR s9 (rf' 4) ix'+ )++ -- Add a left-most component to an index+ --+ cons :: forall sh. Shape sh => Int -> sh -> (sh :. Int)+ cons ix extent = toElt $ go (eltType (undefined::sh)) (fromElt extent)+ where+ go :: TupleType t -> t -> (t, Int)+ go UnitTuple () = ((), ix)+ go (PairTuple th tz) (sh, sz)+ | SingleTuple t <- tz+ , Just Refl <- matchScalarType t (scalarType :: ScalarType Int)+ = (go th sh, sz)+ go _ _+ = $internalError "cons" "expected index with Int components"++ -- Remove the left-most index of an index, and return the remainder+ --+ uncons :: forall sh. Shape sh => sh :. Int -> (Int, sh)+ uncons extent = let (i,ix) = go (eltType (undefined::(sh:.Int))) (fromElt extent)+ in (i, toElt ix)+ where+ go :: TupleType (t, Int) -> (t, Int) -> (Int, t)+ go (PairTuple UnitTuple _) ((), v) = (v, ())+ go (PairTuple t1@(PairTuple _ t2) _) (v1,v3)+ | SingleTuple t <- t2+ , Just Refl <- matchScalarType t (scalarType :: ScalarType Int)+ = let (i, v1') = go t1 v1+ in (i, (v1', v3))+ go _ _+ = $internalError "uncons" "expected index with Int components"+++bounded+ :: (Shape sh, Elt e)+ => Boundary (Array sh e)+ -> Array sh e+ -> sh+ -> e+bounded bnd arr ix =+ if inside (shape arr) ix+ then arr ! ix+ else+ case bnd of+ Function f -> f ix+ Constant v -> toElt v+ _ -> arr ! bound (shape arr) ix++ where+ -- Whether the index (second argument) is inside the bounds of the given+ -- shape (first argument).+ --+ inside :: forall sh. Shape sh => sh -> sh -> Bool+ inside sh1 ix1 = go (eltType (undefined::sh)) (fromElt sh1) (fromElt ix1)+ where+ go :: TupleType t -> t -> t -> Bool+ go UnitTuple () () = True+ go (PairTuple tsh ti) (sh, sz) (ih,iz)+ = if go ti sz iz+ then go tsh sh ih+ else False+ go (SingleTuple t) sz iz+ | Just Refl <- matchScalarType t (scalarType :: ScalarType Int)+ = if iz < 0 || iz >= sz+ then False+ else True+ --+ | otherwise+ = $internalError "inside" "expected index with Int components"++ -- Return the index (second argument), updated to obey the given boundary+ -- conditions when outside the bounds of the given shape (first argument)+ --+ bound :: forall sh. Shape sh => sh -> sh -> sh+ bound sh1 ix1 = toElt $ go (eltType (undefined::sh)) (fromElt sh1) (fromElt ix1)+ where+ go :: TupleType t -> t -> t -> t+ go UnitTuple () () = ()+ go (PairTuple tsh ti) (sh, sz) (ih, iz) = (go tsh sh ih, go ti sz iz)+ go (SingleTuple t) sz iz+ | Just Refl <- matchScalarType t (scalarType :: ScalarType Int)+ = let i | iz < 0 = case bnd of+ Clamp -> 0+ Mirror -> -iz+ Wrap -> sz + iz+ _ -> $internalError "bound" "unexpected boundary condition"+ | iz >= sz = case bnd of+ Clamp -> sz - 1+ Mirror -> sz - (iz - sz + 2)+ Wrap -> iz - sz+ _ -> $internalError "bound" "unexpected boundary condition"+ | otherwise = iz+ in i+ | otherwise+ = $internalError "bound" "expected index with Int components"++ -- toSeqOp :: forall slix sl dim co e proxy. (Elt slix, Shape sl, Shape dim, Elt e) -- => SliceIndex (EltRepr slix) -- (EltRepr sl)@@ -678,6 +887,28 @@ -- toSeqOp sliceIndex _ arr = map (sliceOp sliceIndex arr :: slix -> Array sl e) -- (enumSlices sliceIndex (shape arr)) ++-- Stencil boundary conditions+-- ---------------------------++data Boundary t where+ Clamp :: Boundary t+ Mirror :: Boundary t+ Wrap :: Boundary t+ Constant :: Elt t => EltRepr t -> Boundary (Array sh t)+ Function :: (Shape sh, Elt e) => (sh -> e) -> Boundary (Array sh e)+++evalPreBoundary :: EvalAcc acc -> AST.PreBoundary acc aenv t -> Val aenv -> Boundary t+evalPreBoundary evalAcc bnd aenv =+ case bnd of+ AST.Clamp -> Clamp+ AST.Mirror -> Mirror+ AST.Wrap -> Wrap+ AST.Constant v -> Constant v+ AST.Function f -> Function (evalPreFun evalAcc f aenv)++ -- Scalar expression evaluation -- ---------------------------- @@ -845,6 +1076,7 @@ evalPrim (PrimCeiling ta tb) = evalCeiling ta tb evalPrim (PrimAtan2 ty) = evalAtan2 ty evalPrim (PrimIsNaN ty) = evalIsNaN ty+evalPrim (PrimIsInfinite ty) = evalIsInfinite ty evalPrim (PrimLt ty) = evalLt ty evalPrim (PrimGt ty) = evalGt ty evalPrim (PrimLtEq ty) = evalLtEq ty@@ -1034,6 +1266,9 @@ evalIsNaN :: FloatingType a -> (a -> Bool) evalIsNaN ty | FloatingDict <- floatingDict ty = isNaN++evalIsInfinite :: FloatingType a -> (a -> Bool)+evalIsInfinite ty | FloatingDict <- floatingDict ty = isInfinite -- Methods of Num
Data/Array/Accelerate/Language.hs view
@@ -68,8 +68,10 @@ stencil, stencil2, -- ** Stencil specification- Boundary(..), Stencil,+ Boundary, Stencil,+ clamp, mirror, wrap, function, + -- ** Common stencil types Stencil3, Stencil5, Stencil7, Stencil9, Stencil3x3, Stencil5x3, Stencil3x5, Stencil5x5,@@ -106,14 +108,19 @@ ) where -- friends-import Data.Array.Accelerate.Array.Sugar hiding ((!), ignore, shape, size, toIndex, fromIndex, intersect, union)-import Data.Array.Accelerate.Classes+import Data.Array.Accelerate.Array.Sugar hiding ( (!), ignore, shape, size, toIndex, fromIndex, intersect, union ) import Data.Array.Accelerate.Smart import Data.Array.Accelerate.Type-import qualified Data.Array.Accelerate.Array.Sugar as Sugar+import qualified Data.Array.Accelerate.Array.Sugar as Sugar +import Data.Array.Accelerate.Classes.Eq+import Data.Array.Accelerate.Classes.Fractional+import Data.Array.Accelerate.Classes.Integral+import Data.Array.Accelerate.Classes.Num+import Data.Array.Accelerate.Classes.Ord+ -- standard libraries-import Prelude ( ($), (.) )+import Prelude ( ($), (.) ) -- Array introduction@@ -279,7 +286,7 @@ -- -- > precondition: shapeSize sh == shapeSize sh' ----- If the argument array is manifest in memory, 'reshape' is a NOP. If the+-- If the argument array is manifest in memory, 'reshape' is a no-op. If the -- argument is to be fused into a subsequent operation, 'reshape' corresponds to -- an index transformation in the fused code. --@@ -293,9 +300,9 @@ -- Extraction of sub-arrays -- ------------------------ --- | Index an array with a /generalised/ array index, supplied as the--- second argument. The result is a new array (possibly a singleton)--- containing the selected dimensions (`All`s) in their entirety.+-- | Index an array with a /generalised/ array index, supplied as the second+-- argument. The result is a new array (possibly a singleton) containing the+-- selected dimensions ('All's) in their entirety. -- -- 'slice' is the opposite of 'replicate', and can be used to /cut out/ entire -- dimensions. For example, for the two dimensional array 'mat':@@ -362,10 +369,17 @@ -- Map-like functions -- ------------------ --- | Apply the given function element-wise to an array.+-- | Apply the given function element-wise to an array. Denotationally we have: -- -- > map f [x1, x2, ... xn] = [f x1, f x2, ... f xn] --+-- >>> let xs = fromList (Z:.10) [0..]+-- >>> xs+-- Vector (Z :. 10) [0,1,2,3,4,5,6,7,8,9]+--+-- >>> map (+1) (use xs)+-- Vector (Z :. 10) [1,2,3,4,5,6,7,8,9,10]+-- map :: (Shape sh, Elt a, Elt b) => (Exp a -> Exp b) -> Acc (Array sh a)@@ -376,6 +390,28 @@ -- of the resulting array is the intersection of the extents of the two source -- arrays. --+-- >>> let xs = fromList (Z:.3:.5) [0..]+-- >>> xs+-- Matrix (Z :. 3 :. 5)+-- [ 0, 1, 2, 3, 4,+-- 5, 6, 7, 8, 9,+-- 10,11,12,13,14]+--+-- >>> let ys = fromList (Z:.5:.10) [1..]+-- >>> ys+-- Matrix (Z :. 5 :. 10)+-- [ 1, 2, 3, 4, 5, 6, 7, 8, 9,10,+-- 11,12,13,14,15,16,17,18,19,20,+-- 21,22,23,24,25,26,27,28,29,30,+-- 31,32,33,34,35,36,37,38,39,40,+-- 41,42,43,44,45,46,47,48,49,50]+--+-- >>> zipWith (+) (use xs) (use ys)+-- Matrix (Z :. 3 :. 5)+-- [ 1, 3, 5, 7, 9,+-- 16,18,20,22,24,+-- 31,33,35,37,39]+-- zipWith :: (Shape sh, Elt a, Elt b, Elt c) => (Exp a -> Exp b -> Exp c) -> Acc (Array sh a)@@ -558,8 +594,8 @@ => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh:.Int) a)- -> (Acc (Array (sh:.Int) a), Acc (Array sh a))-scanl' = unatup2 . Acc $$$ Scanl'+ -> Acc (Array (sh:.Int) a, Array sh a)+scanl' = Acc $$$ Scanl' -- | Data.List style left-to-right scan along the innermost dimension without an -- initial value (aka inclusive scan). The array must not be empty. The first@@ -567,7 +603,8 @@ -- -- > scanl1 f e arr = tail (scanl f e arr) ----- >>> scanl (+) (use $ fromList (Z:.4:.10) [0..])+-- >>> let mat = fromList (Z:.4:.10) [0..]+-- >>> scanl (+) (use mat) -- Matrix (Z :. 4 :. 10) -- [ 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, -- 10, 21, 33, 46, 60, 75, 91, 108, 126, 145,@@ -595,8 +632,8 @@ => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Array (sh:.Int) a)- -> (Acc (Array (sh:.Int) a), Acc (Array sh a))-scanr' = unatup2 . Acc $$$ Scanr'+ -> Acc (Array (sh:.Int) a, Array sh a)+scanr' = Acc $$$ Scanr' -- | Right-to-left variant of 'scanl1'. --@@ -620,6 +657,9 @@ -- that are mapped to the magic value 'ignore' by the permutation function are -- dropped. --+-- The combination function is given the new value being permuted as its first+-- argument, and the current value of the array as its second.+-- -- For example, we can use 'permute' to compute the occurrence count (histogram) -- for an array of values in the range @[0,10)@: --@@ -634,6 +674,25 @@ -- >>> histogram (use xs) -- Vector (Z :. 10) [2,4,4,3,2,2,0,0,2,1] --+-- As a second example, note that the dimensionality of the source and+-- destination arrays can differ. In this way, we can use 'permute' to create an+-- identity matrix by overwriting elements along the diagonal:+--+-- > identity :: Num a => Exp Int -> Acc (Array DIM2 a)+-- > identity n =+-- > let zeros = fill (index2 n n) 0+-- > ones = fill (index1 n) 1+-- > in+-- > permute const zeros (\(unindex1 -> i) -> index2 i i) ones+--+-- >>> identity 5+-- Matrix (Z :. 5 :. 5)+-- [1,0,0,0,0,+-- 0,1,0,0,0,+-- 0,0,1,0,0,+-- 0,0,0,1,0,+-- 0,0,0,0,1]+-- -- [/Note:/] -- -- Regarding array fusion:@@ -647,6 +706,9 @@ -- -- 3. The array of source values can fuse into the permutation operation. --+-- 4. If the array of default values is only used once, it will be updated+-- in-place.+-- permute :: (Shape sh, Shape sh', Elt a) => (Exp a -> Exp a -> Exp a) -- ^ combination function@@ -756,8 +818,8 @@ -- -- > s33 :: Stencil3x3 a -> Exp a -- > s33 ((_,t,_)--- ,(l,c,r)--- ,(_,b,_)) = ...+-- > ,(l,c,r)+-- > ,(_,b,_)) = ... -- -- ...where @c@ is again the focal point and @t@, @b@, @l@ and @r@ are the -- elements to the top, bottom, left, and right of the focal point, respectively@@ -781,16 +843,16 @@ -- > gaussian = [0.06136,0.24477,0.38774,0.24477,0.06136] -- > -- > blur :: Num a => Acc (Array DIM2 a) -> Acc (Array DIM2 a)--- > blur = stencil (convolve5x1 gaussian) Clamp--- > . stencil (convolve1x5 gaussian) Clamp+-- > blur = stencil (convolve5x1 gaussian) clamp+-- > . stencil (convolve1x5 gaussian) clamp -- stencil :: (Stencil sh a stencil, Elt b) => (stencil -> Exp b) -- ^ stencil function- -> Boundary a -- ^ boundary condition+ -> Boundary (Array sh a) -- ^ boundary condition -> Acc (Array sh a) -- ^ source array -> Acc (Array sh b) -- ^ destination array-stencil = Acc $$$ Stencil+stencil f (Boundary b) a = Acc $ Stencil f b a -- | Map a binary stencil of an array. The extent of the resulting array is the -- intersection of the extents of the two source arrays. This is the stencil@@ -799,14 +861,70 @@ stencil2 :: (Stencil sh a stencil1, Stencil sh b stencil2, Elt c) => (stencil1 -> stencil2 -> Exp c) -- ^ binary stencil function- -> Boundary a -- ^ boundary condition #1+ -> Boundary (Array sh a) -- ^ boundary condition #1 -> Acc (Array sh a) -- ^ source array #1- -> Boundary b -- ^ boundary condition #2+ -> Boundary (Array sh b) -- ^ boundary condition #2 -> Acc (Array sh b) -- ^ source array #2 -> Acc (Array sh c) -- ^ destination array-stencil2 = Acc $$$$$ Stencil2+stencil2 f (Boundary b1) a1 (Boundary b2) a2 = Acc $ Stencil2 f b1 a1 b2 a2 +-- | Boundary condition where elements of the stencil which would be+-- out-of-bounds are instead clamped to the edges of the array.+--+-- In the following 3x3 stencil, the out-of-bounds element @b@ will instead+-- return the value at position @c@:+--+-- > +------------++-- > |a |+-- > b|cd |+-- > |e |+-- > +------------++--+clamp :: Boundary (Array sh e)+clamp = Boundary Clamp +-- | Stencil boundary condition where coordinates beyond the array extent are+-- instead mirrored+--+-- In the following 5x3 stencil, the out-of-bounds element @c@ will instead+-- return the value at position @d@, and similarly the element at @b@ will+-- return the value at @e@:+--+-- > +------------++-- > |a |+-- > bc|def |+-- > |g |+-- > +------------++--+mirror :: Boundary (Array sh e)+mirror = Boundary Mirror++-- | Stencil boundary condition where coordinates beyond the array extent+-- instead wrap around the array.+--+-- In the following 3x3 stencil, the out of bounds elements will be read as in+-- the pattern on the right.+--+-- > a bc+-- > +------------+ +------------++-- > d|ef | |ef d|+-- > g|hi | -> |hi g|+-- > | | |bc a|+-- > +------------+ +------------++--+wrap :: Boundary (Array sh e)+wrap = Boundary Wrap++-- | Stencil boundary condition where the given function is applied to any+-- outlying coordinates.+--+function+ :: (Shape sh, Elt e)+ => (Exp sh -> Exp e)+ -> Boundary (Array sh e)+function = Boundary . Function++ {-- -- Sequence operations -- ------------------@@ -923,7 +1041,7 @@ -- In case the operation is being executed on a backend which does not support -- this foreign implementation, the fallback implementation is used instead, -- which itself could be a foreign implementation for a (presumably) different--- backend, or an implementation of pure Accelerate. In this way, multiple+-- backend, or an implementation in pure Accelerate. In this way, multiple -- foreign implementations can be supplied, and will be tested for suitability -- against the target backend in sequence. --@@ -968,6 +1086,9 @@ -- > (acc1 >-> acc2) arrs = let tmp = acc1 arrs -- > in tmp `seq` acc2 tmp --+-- For an example use of this operation see the 'Data.Array.Accelerate.compute'+-- function.+-- infixl 1 >-> (>->) :: (Arrays a, Arrays b, Arrays c) => (Acc a -> Acc b) -> (Acc b -> Acc c) -> (Acc a -> Acc c) (>->) = Acc $$$ Pipe@@ -978,6 +1099,9 @@ -- | An array-level if-then-else construct. --+-- Enabling the @RebindableSyntax@ extension will allow you to use the standard+-- if-then-else syntax instead.+-- acond :: Arrays a => Exp Bool -- ^ if-condition -> Acc a -- ^ then-array@@ -1000,8 +1124,16 @@ -- Shapes and indices -- ------------------ --- | Get the innermost dimension of a shape+-- | Get the innermost dimension of a shape. --+-- The innermost dimension (right-most component of the shape) is the index of+-- the array which varies most rapidly, and corresponds to elements of the array+-- which are adjacent in memory.+--+-- Another way to think of this is, for example when writing nested loops over+-- an array in C, this index corresponds to the index iterated over by the+-- innermost nested loop.+-- indexHead :: (Slice sh, Elt a) => Exp (sh :. a) -> Exp a indexHead = Exp . IndexHead @@ -1040,6 +1172,9 @@ -- ------------ -- | A scalar-level if-then-else construct.+--+-- Enabling the @RebindableSyntax@ extension will allow you to use the standard+-- if-then-else syntax instead. -- cond :: Elt t => Exp Bool -- ^ condition
Data/Array/Accelerate/Lifetime.hs view
@@ -61,6 +61,7 @@ -- | Construct a new 'Lifetime' from the given value. --+{-# INLINE newLifetime #-} newLifetime :: a -> IO (Lifetime a) newLifetime a = do ref <- newIORef []@@ -72,6 +73,7 @@ -- throughout its execution. It is important to not let the value /leak/ outside -- the function, either by returning it or by lazy IO. --+{-# INLINE withLifetime #-} withLifetime :: Lifetime a -> (a -> IO b) -> IO b withLifetime (Lifetime ref _ a) f = do r <- f a@@ -81,6 +83,7 @@ -- | Ensure that the lifetime is alive at the given place in a sequence of IO -- actions. Does not force the payload. --+{-# INLINE touchLifetime #-} touchLifetime :: Lifetime a -> IO () touchLifetime (Lifetime ref _ _) = touchIORef ref @@ -138,6 +141,7 @@ -- 'Lifetime' is still reachable, the finalizers may fire, potentially -- invalidating the value. --+{-# INLINE unsafeGetValue #-} unsafeGetValue :: Lifetime a -> a unsafeGetValue (Lifetime _ _ a) = a @@ -151,6 +155,7 @@ -- Touch an 'IORef', ensuring that it is alive at this point in a sequence of IO -- actions. --+{-# INLINE touchIORef #-} touchIORef :: IORef a -> IO () touchIORef r = IO $ \s -> case touch# r s of s' -> (# s', () #)
Data/Array/Accelerate/Prelude.hs view
@@ -112,17 +112,21 @@ import Data.Typeable ( gcast ) import GHC.Base ( Constraint ) import Prelude ( (.), ($), Maybe(..), const, id, fromInteger, flip, undefined, fail )-import qualified Prelude as P -- friends import Data.Array.Accelerate.Analysis.Match import Data.Array.Accelerate.Array.Sugar hiding ( (!), ignore, shape, size, intersect, toIndex, fromIndex )-import Data.Array.Accelerate.Classes import Data.Array.Accelerate.Language import Data.Array.Accelerate.Lift import Data.Array.Accelerate.Smart import Data.Array.Accelerate.Type +import Data.Array.Accelerate.Classes.Eq+import Data.Array.Accelerate.Classes.FromIntegral+import Data.Array.Accelerate.Classes.Integral+import Data.Array.Accelerate.Classes.Num+import Data.Array.Accelerate.Classes.Ord+ import Data.Array.Accelerate.Data.Bits @@ -131,6 +135,17 @@ -- | Pair each element with its index --+-- >>> let xs = fromList (Z:.5) [0..]+-- >>> indexed (use xs)+-- Vector (Z :. 5) [(Z :. 0,0.0),(Z :. 1,1.0),(Z :. 2,2.0),(Z :. 3,3.0),(Z :. 4,4.0)]+--+-- >>> let mat = fromList (Z:.3:.4) [0..]+-- >>> indexed (use mat)+-- Matrix (Z :. 3 :. 4)+-- [(Z :. 0 :. 0,0.0),(Z :. 0 :. 1,1.0), (Z :. 0 :. 2,2.0), (Z :. 0 :. 3,3.0),+-- (Z :. 1 :. 0,4.0),(Z :. 1 :. 1,5.0), (Z :. 1 :. 2,6.0), (Z :. 1 :. 3,7.0),+-- (Z :. 2 :. 0,8.0),(Z :. 2 :. 1,9.0),(Z :. 2 :. 2,10.0),(Z :. 2 :. 3,11.0)]+-- indexed :: (Shape sh, Elt a) => Acc (Array sh a) -> Acc (Array sh (sh, a)) indexed xs = zip (generate (shape xs) id) xs @@ -145,25 +160,27 @@ -- | Zip three arrays with the given function, analogous to 'zipWith'. ---zipWith3 :: (Shape sh, Elt a, Elt b, Elt c, Elt d)- => (Exp a -> Exp b -> Exp c -> Exp d)- -> Acc (Array sh a)- -> Acc (Array sh b)- -> Acc (Array sh c)- -> Acc (Array sh d)+zipWith3+ :: (Shape sh, Elt a, Elt b, Elt c, Elt d)+ => (Exp a -> Exp b -> Exp c -> Exp d)+ -> Acc (Array sh a)+ -> Acc (Array sh b)+ -> Acc (Array sh c)+ -> Acc (Array sh d) zipWith3 f as bs cs = generate (shape as `intersect` shape bs `intersect` shape cs) (\ix -> f (as ! ix) (bs ! ix) (cs ! ix)) -- | Zip four arrays with the given function, analogous to 'zipWith'. ---zipWith4 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e)- => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e)- -> Acc (Array sh a)- -> Acc (Array sh b)- -> Acc (Array sh c)- -> Acc (Array sh d)- -> Acc (Array sh e)+zipWith4+ :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e)+ => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e)+ -> Acc (Array sh a)+ -> Acc (Array sh b)+ -> Acc (Array sh c)+ -> Acc (Array sh d)+ -> Acc (Array sh e) zipWith4 f as bs cs ds = generate (shape as `intersect` shape bs `intersect` shape cs `intersect` shape ds)@@ -171,14 +188,15 @@ -- | Zip five arrays with the given function, analogous to 'zipWith'. ---zipWith5 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f)- => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f)- -> Acc (Array sh a)- -> Acc (Array sh b)- -> Acc (Array sh c)- -> Acc (Array sh d)- -> Acc (Array sh e)- -> Acc (Array sh f)+zipWith5+ :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f)+ => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f)+ -> Acc (Array sh a)+ -> Acc (Array sh b)+ -> Acc (Array sh c)+ -> Acc (Array sh d)+ -> Acc (Array sh e)+ -> Acc (Array sh f) zipWith5 f as bs cs ds es = generate (shape as `intersect` shape bs `intersect` shape cs `intersect` shape ds `intersect` shape es)@@ -186,15 +204,16 @@ -- | Zip six arrays with the given function, analogous to 'zipWith'. ---zipWith6 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g)- => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g)- -> Acc (Array sh a)- -> Acc (Array sh b)- -> Acc (Array sh c)- -> Acc (Array sh d)- -> Acc (Array sh e)- -> Acc (Array sh f)- -> Acc (Array sh g)+zipWith6+ :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g)+ => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g)+ -> Acc (Array sh a)+ -> Acc (Array sh b)+ -> Acc (Array sh c)+ -> Acc (Array sh d)+ -> Acc (Array sh e)+ -> Acc (Array sh f)+ -> Acc (Array sh g) zipWith6 f as bs cs ds es fs = generate (shape as `intersect` shape bs `intersect` shape cs `intersect` shape ds `intersect` shape es@@ -203,16 +222,17 @@ -- | Zip seven arrays with the given function, analogous to 'zipWith'. ---zipWith7 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h)- => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h)- -> Acc (Array sh a)- -> Acc (Array sh b)- -> Acc (Array sh c)- -> Acc (Array sh d)- -> Acc (Array sh e)- -> Acc (Array sh f)- -> Acc (Array sh g)- -> Acc (Array sh h)+zipWith7+ :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h)+ => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h)+ -> Acc (Array sh a)+ -> Acc (Array sh b)+ -> Acc (Array sh c)+ -> Acc (Array sh d)+ -> Acc (Array sh e)+ -> Acc (Array sh f)+ -> Acc (Array sh g)+ -> Acc (Array sh h) zipWith7 f as bs cs ds es fs gs = generate (shape as `intersect` shape bs `intersect` shape cs `intersect` shape ds `intersect` shape es@@ -221,17 +241,18 @@ -- | Zip eight arrays with the given function, analogous to 'zipWith'. ---zipWith8 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i)- => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i)- -> Acc (Array sh a)- -> Acc (Array sh b)- -> Acc (Array sh c)- -> Acc (Array sh d)- -> Acc (Array sh e)- -> Acc (Array sh f)- -> Acc (Array sh g)- -> Acc (Array sh h)- -> Acc (Array sh i)+zipWith8+ :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i)+ => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i)+ -> Acc (Array sh a)+ -> Acc (Array sh b)+ -> Acc (Array sh c)+ -> Acc (Array sh d)+ -> Acc (Array sh e)+ -> Acc (Array sh f)+ -> Acc (Array sh g)+ -> Acc (Array sh h)+ -> Acc (Array sh i) zipWith8 f as bs cs ds es fs gs hs = generate (shape as `intersect` shape bs `intersect` shape cs `intersect` shape ds `intersect` shape es@@ -241,18 +262,19 @@ -- | Zip nine arrays with the given function, analogous to 'zipWith'. ---zipWith9 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j)- => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i -> Exp j)- -> Acc (Array sh a)- -> Acc (Array sh b)- -> Acc (Array sh c)- -> Acc (Array sh d)- -> Acc (Array sh e)- -> Acc (Array sh f)- -> Acc (Array sh g)- -> Acc (Array sh h)- -> Acc (Array sh i)- -> Acc (Array sh j)+zipWith9+ :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j)+ => (Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i -> Exp j)+ -> Acc (Array sh a)+ -> Acc (Array sh b)+ -> Acc (Array sh c)+ -> Acc (Array sh d)+ -> Acc (Array sh e)+ -> Acc (Array sh f)+ -> Acc (Array sh g)+ -> Acc (Array sh h)+ -> Acc (Array sh i)+ -> Acc (Array sh j) zipWith9 f as bs cs ds es fs gs hs is = generate (shape as `intersect` shape bs `intersect` shape cs `intersect` shape ds `intersect` shape es@@ -263,11 +285,12 @@ -- | Zip two arrays with a function that also takes the element index ---izipWith :: (Shape sh, Elt a, Elt b, Elt c)- => (Exp sh -> Exp a -> Exp b -> Exp c)- -> Acc (Array sh a)- -> Acc (Array sh b)- -> Acc (Array sh c)+izipWith+ :: (Shape sh, Elt a, Elt b, Elt c)+ => (Exp sh -> Exp a -> Exp b -> Exp c)+ -> Acc (Array sh a)+ -> Acc (Array sh b)+ -> Acc (Array sh c) izipWith f as bs = generate (shape as `intersect` shape bs) (\ix -> f ix (as ! ix) (bs ! ix))@@ -275,12 +298,13 @@ -- | Zip three arrays with a function that also takes the element index, -- analogous to 'izipWith'. ---izipWith3 :: (Shape sh, Elt a, Elt b, Elt c, Elt d)- => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d)- -> Acc (Array sh a)- -> Acc (Array sh b)- -> Acc (Array sh c)- -> Acc (Array sh d)+izipWith3+ :: (Shape sh, Elt a, Elt b, Elt c, Elt d)+ => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d)+ -> Acc (Array sh a)+ -> Acc (Array sh b)+ -> Acc (Array sh c)+ -> Acc (Array sh d) izipWith3 f as bs cs = generate (shape as `intersect` shape bs `intersect` shape cs) (\ix -> f ix (as ! ix) (bs ! ix) (cs ! ix))@@ -288,13 +312,14 @@ -- | Zip four arrays with the given function that also takes the element index, -- analogous to 'zipWith'. ---izipWith4 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e)- => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e)- -> Acc (Array sh a)- -> Acc (Array sh b)- -> Acc (Array sh c)- -> Acc (Array sh d)- -> Acc (Array sh e)+izipWith4+ :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e)+ => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e)+ -> Acc (Array sh a)+ -> Acc (Array sh b)+ -> Acc (Array sh c)+ -> Acc (Array sh d)+ -> Acc (Array sh e) izipWith4 f as bs cs ds = generate (shape as `intersect` shape bs `intersect` shape cs `intersect` shape ds)@@ -303,14 +328,15 @@ -- | Zip five arrays with the given function that also takes the element index, -- analogous to 'zipWith'. ---izipWith5 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f)- => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f)- -> Acc (Array sh a)- -> Acc (Array sh b)- -> Acc (Array sh c)- -> Acc (Array sh d)- -> Acc (Array sh e)- -> Acc (Array sh f)+izipWith5+ :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f)+ => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f)+ -> Acc (Array sh a)+ -> Acc (Array sh b)+ -> Acc (Array sh c)+ -> Acc (Array sh d)+ -> Acc (Array sh e)+ -> Acc (Array sh f) izipWith5 f as bs cs ds es = generate (shape as `intersect` shape bs `intersect` shape cs `intersect` shape ds `intersect` shape es)@@ -319,15 +345,16 @@ -- | Zip six arrays with the given function that also takes the element index, -- analogous to 'zipWith'. ---izipWith6 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g)- => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g)- -> Acc (Array sh a)- -> Acc (Array sh b)- -> Acc (Array sh c)- -> Acc (Array sh d)- -> Acc (Array sh e)- -> Acc (Array sh f)- -> Acc (Array sh g)+izipWith6+ :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g)+ => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g)+ -> Acc (Array sh a)+ -> Acc (Array sh b)+ -> Acc (Array sh c)+ -> Acc (Array sh d)+ -> Acc (Array sh e)+ -> Acc (Array sh f)+ -> Acc (Array sh g) izipWith6 f as bs cs ds es fs = generate (shape as `intersect` shape bs `intersect` shape cs `intersect` shape ds `intersect` shape es@@ -337,16 +364,17 @@ -- | Zip seven arrays with the given function that also takes the element -- index, analogous to 'zipWith'. ---izipWith7 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h)- => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h)- -> Acc (Array sh a)- -> Acc (Array sh b)- -> Acc (Array sh c)- -> Acc (Array sh d)- -> Acc (Array sh e)- -> Acc (Array sh f)- -> Acc (Array sh g)- -> Acc (Array sh h)+izipWith7+ :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h)+ => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h)+ -> Acc (Array sh a)+ -> Acc (Array sh b)+ -> Acc (Array sh c)+ -> Acc (Array sh d)+ -> Acc (Array sh e)+ -> Acc (Array sh f)+ -> Acc (Array sh g)+ -> Acc (Array sh h) izipWith7 f as bs cs ds es fs gs = generate (shape as `intersect` shape bs `intersect` shape cs `intersect` shape ds `intersect` shape es@@ -356,17 +384,18 @@ -- | Zip eight arrays with the given function that also takes the element -- index, analogous to 'zipWith'. ---izipWith8 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i)- => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i)- -> Acc (Array sh a)- -> Acc (Array sh b)- -> Acc (Array sh c)- -> Acc (Array sh d)- -> Acc (Array sh e)- -> Acc (Array sh f)- -> Acc (Array sh g)- -> Acc (Array sh h)- -> Acc (Array sh i)+izipWith8+ :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i)+ => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i)+ -> Acc (Array sh a)+ -> Acc (Array sh b)+ -> Acc (Array sh c)+ -> Acc (Array sh d)+ -> Acc (Array sh e)+ -> Acc (Array sh f)+ -> Acc (Array sh g)+ -> Acc (Array sh h)+ -> Acc (Array sh i) izipWith8 f as bs cs ds es fs gs hs = generate (shape as `intersect` shape bs `intersect` shape cs `intersect` shape ds `intersect` shape es@@ -377,18 +406,19 @@ -- | Zip nine arrays with the given function that also takes the element index, -- analogous to 'zipWith'. ---izipWith9 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j)- => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i -> Exp j)- -> Acc (Array sh a)- -> Acc (Array sh b)- -> Acc (Array sh c)- -> Acc (Array sh d)- -> Acc (Array sh e)- -> Acc (Array sh f)- -> Acc (Array sh g)- -> Acc (Array sh h)- -> Acc (Array sh i)- -> Acc (Array sh j)+izipWith9+ :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j)+ => (Exp sh -> Exp a -> Exp b -> Exp c -> Exp d -> Exp e -> Exp f -> Exp g -> Exp h -> Exp i -> Exp j)+ -> Acc (Array sh a)+ -> Acc (Array sh b)+ -> Acc (Array sh c)+ -> Acc (Array sh d)+ -> Acc (Array sh e)+ -> Acc (Array sh f)+ -> Acc (Array sh g)+ -> Acc (Array sh h)+ -> Acc (Array sh i)+ -> Acc (Array sh j) izipWith9 f as bs cs ds es fs gs hs is = generate (shape as `intersect` shape bs `intersect` shape cs `intersect` shape ds `intersect` shape es@@ -494,14 +524,14 @@ -- | The converse of 'zip', but the shape of the two results is identical to the -- shape of the argument. ----- If the argument array is manifest in memory, 'unzip' is a NOP.+-- If the argument array is manifest in memory, 'unzip' is a no-op. -- unzip :: (Shape sh, Elt a, Elt b) => Acc (Array sh (a, b)) -> (Acc (Array sh a), Acc (Array sh b)) unzip arr = (map fst arr, map snd arr) --- | Take an array of triples and return three arrays, analogous to unzip.+-- | Take an array of triples and return three arrays, analogous to 'unzip'. -- unzip3 :: (Shape sh, Elt a, Elt b, Elt c) => Acc (Array sh (a, b, c))@@ -513,7 +543,7 @@ get3 x = let (_,_,c) = untup3 x in c --- | Take an array of quadruples and return four arrays, analogous to unzip.+-- | Take an array of quadruples and return four arrays, analogous to 'unzip'. -- unzip4 :: (Shape sh, Elt a, Elt b, Elt c, Elt d) => Acc (Array sh (a, b, c, d))@@ -525,7 +555,7 @@ get3 x = let (_,_,c,_) = untup4 x in c get4 x = let (_,_,_,d) = untup4 x in d --- | Take an array of 5-tuples and return five arrays, analogous to unzip.+-- | Take an array of 5-tuples and return five arrays, analogous to 'unzip'. -- unzip5 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e) => Acc (Array sh (a, b, c, d, e))@@ -538,7 +568,7 @@ get4 x = let (_,_,_,d,_) = untup5 x in d get5 x = let (_,_,_,_,e) = untup5 x in e --- | Take an array of 6-tuples and return six arrays, analogous to unzip.+-- | Take an array of 6-tuples and return six arrays, analogous to 'unzip'. -- unzip6 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f) => Acc (Array sh (a, b, c, d, e, f))@@ -553,7 +583,7 @@ get5 x = let (_,_,_,_,e,_) = untup6 x in e get6 x = let (_,_,_,_,_,f) = untup6 x in f --- | Take an array of 7-tuples and return seven arrays, analogous to unzip.+-- | Take an array of 7-tuples and return seven arrays, analogous to 'unzip'. -- unzip7 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g) => Acc (Array sh (a, b, c, d, e, f, g))@@ -572,7 +602,7 @@ get6 x = let (_,_,_,_,_,f,_) = untup7 x in f get7 x = let (_,_,_,_,_,_,g) = untup7 x in g --- | Take an array of 8-tuples and return eight arrays, analogous to unzip.+-- | Take an array of 8-tuples and return eight arrays, analogous to 'unzip'. -- unzip8 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h) => Acc (Array sh (a, b, c, d, e, f, g, h))@@ -592,7 +622,7 @@ get7 x = let (_,_,_,_,_,_,g,_) = untup8 x in g get8 x = let (_,_,_,_,_,_,_,h) = untup8 x in h --- | Take an array of 8-tuples and return eight arrays, analogous to unzip.+-- | Take an array of 8-tuples and return eight arrays, analogous to 'unzip'. -- unzip9 :: (Shape sh, Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i) => Acc (Array sh (a, b, c, d, e, f, g, h, i))@@ -629,21 +659,23 @@ -- >>> foldAll (+) 0 (use mat) -- Scalar Z [1225] ---foldAll :: (Shape sh, Elt a)- => (Exp a -> Exp a -> Exp a)- -> Exp a- -> Acc (Array sh a)- -> Acc (Scalar a)+foldAll+ :: (Shape sh, Elt a)+ => (Exp a -> Exp a -> Exp a)+ -> Exp a+ -> Acc (Array sh a)+ -> Acc (Scalar a) foldAll f e arr = fold f e (flatten arr) -- | Variant of 'foldAll' that requires the reduced array to be non-empty and--- doesn't need an default value. The first argument must be an /associative/+-- does not need a default value. The first argument must be an /associative/ -- function. ---fold1All :: (Shape sh, Elt a)- => (Exp a -> Exp a -> Exp a)- -> Acc (Array sh a)- -> Acc (Scalar a)+fold1All+ :: (Shape sh, Elt a)+ => (Exp a -> Exp a -> Exp a)+ -> Acc (Array sh a)+ -> Acc (Scalar a) fold1All f arr = fold1 f (flatten arr) @@ -653,121 +685,185 @@ -- Leave the results of these as scalar arrays to make it clear that these are -- array computations, and thus can not be nested. --- | Check if all elements satisfy a predicate+-- | Check if all elements along the innermost dimension satisfy a predicate. --+-- >>> let mat = fromList (Z :. 4 :. 10) [1,2,3,4,5,6,7,8,9,10,1,1,1,1,1,2,2,2,2,2,2,4,6,8,10,12,14,16,18,20,1,3,5,7,9,11,13,15,17,19] :: Array DIM2 Int+-- >>> mat+-- Matrix (Z :. 4 :. 10)+-- [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,+-- 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,+-- 2, 4, 6, 8, 10, 12, 14, 16, 18, 20,+-- 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]+--+-- >>> all even (use mat)+-- Vector (Z :. 4) [False,False,True,False]+-- all :: (Shape sh, Elt e) => (Exp e -> Exp Bool)- -> Acc (Array sh e)- -> Acc (Scalar Bool)+ -> Acc (Array (sh:.Int) e)+ -> Acc (Array sh Bool) all f = and . map f --- | Check if any element satisfies the predicate+-- | Check if any element along the innermost dimension satisfies the predicate. --+-- >>> let mat = fromList (Z :. 4 :. 10) [1,2,3,4,5,6,7,8,9,10,1,1,1,1,1,2,2,2,2,2,2,4,6,8,10,12,14,16,18,20,1,3,5,7,9,11,13,15,17,19] :: Array DIM2 Int+-- >>> mat+-- Matrix (Z :. 4 :. 10)+-- [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,+-- 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,+-- 2, 4, 6, 8, 10, 12, 14, 16, 18, 20,+-- 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]+--+-- >>> any even (use mat)+-- Vector (Z :. 4) [True,True,True,False]+-- any :: (Shape sh, Elt e) => (Exp e -> Exp Bool)- -> Acc (Array sh e)- -> Acc (Scalar Bool)+ -> Acc (Array (sh:.Int) e)+ -> Acc (Array sh Bool) any f = or . map f --- | Check if all elements are 'True'+-- | Check if all elements along the innermost dimension are 'True'. -- and :: Shape sh- => Acc (Array sh Bool)- -> Acc (Scalar Bool)-and = foldAll (&&) (constant True)+ => Acc (Array (sh:.Int) Bool)+ -> Acc (Array sh Bool)+and = fold (&&) (constant True) --- | Check if any element is 'True'+-- | Check if any element along the innermost dimension is 'True'. -- or :: Shape sh- => Acc (Array sh Bool)- -> Acc (Scalar Bool)-or = foldAll (||) (constant False)+ => Acc (Array (sh:.Int) Bool)+ -> Acc (Array sh Bool)+or = fold (||) (constant False) --- | Compute the sum of elements+-- | Compute the sum of elements along the innermost dimension of the array. To+-- find the sum of the entire array, 'flatten' it first. --+-- >>> let mat = fromList (Z:.2:.5) [0..]+-- Vector (Z :. 2) [10,35]+-- sum :: (Shape sh, Num e)- => Acc (Array sh e)- -> Acc (Scalar e)-sum = foldAll (+) 0+ => Acc (Array (sh:.Int) e)+ -> Acc (Array sh e)+sum = fold (+) 0 --- | Compute the product of the elements+-- | Compute the product of the elements along the innermost dimension of the+-- array. To find the product of the entire array, 'flatten' it first. ---product :: (Shape sh, Num e)- => Acc (Array sh e)- -> Acc (Scalar e)-product = foldAll (*) 1+-- >>> let mat = fromList (Z:.2:.5) [0..]+-- Vector (Z :. 2) [0,15120]+--+product+ :: (Shape sh, Num e)+ => Acc (Array (sh:.Int) e)+ -> Acc (Array sh e)+product = fold (*) 1 --- | Yield the minimum element of an array. The array must not be empty.+-- | Yield the minimum element along the innermost dimension of the array. To+-- find find the minimum element of the entire array, 'flatten' it first. ---minimum :: (Shape sh, Ord e)- => Acc (Array sh e)- -> Acc (Scalar e)-minimum = fold1All min+-- The array must not be empty. See also 'fold1'.+--+-- >>> let mat = fromList (Z :. 3 :. 4) [1,4,3,8, 0,2,8,4, 7,9,8,8]+-- >>> mat+-- Matrix (Z :. 3 :. 4)+-- [ 1, 4, 3, 8,+-- 0, 2, 8, 4,+-- 7, 9, 8, 8]+--+-- >>> minimum (use mat)+-- Vector (Z :. 3) [1,0,7]+--+minimum+ :: (Shape sh, Ord e)+ => Acc (Array (sh:.Int) e)+ -> Acc (Array sh e)+minimum = fold1 min --- | Yield the maximum element of an array. The array must not be empty.+-- | Yield the maximum element along the innermost dimension of the array. To+-- find the maximum element of the entire array, 'flatten' it first. ---maximum :: (Shape sh, Ord e)- => Acc (Array sh e)- -> Acc (Scalar e)-maximum = fold1All max+-- The array must not be empty. See also 'fold1'.+--+-- >>> let mat = fromList (Z :. 3 :. 4) [1,4,3,8, 0,2,8,4, 7,9,8,8]+-- >>> mat+-- Matrix (Z :. 3 :. 4)+-- [ 1, 4, 3, 8,+-- 0, 2, 8, 4,+-- 7, 9, 8, 8]+--+-- >>> maximum (use mat)+-- Vector (Z :. 3) [8,8,9]+--+maximum+ :: (Shape sh, Ord e)+ => Acc (Array (sh:.Int) e)+ -> Acc (Array sh e)+maximum = fold1 max -- Composite scans -- --------------- --- | Left-to-right prescan (aka exclusive scan). As for 'scan', the first--- argument must be an /associative/ function. Denotationally, we have+-- | Left-to-right pre-scan (aka exclusive scan). As for 'scan', the first+-- argument must be an /associative/ function. Denotationally, we have: ----- > prescanl f e = Prelude.fst . scanl' f e+-- > prescanl f e = afst . scanl' f e -- -- >>> let vec = fromList (Z:.10) [1..10] -- >>> prescanl (+) 0 (use vec)--- Vector (Z :. 10) [0,0,1,3,6,10,15,21,28,36]+-- Vector (Z :. 10) [0,1,3,6,10,15,21,28,36,45] ---prescanl :: (Shape sh, Elt a)- => (Exp a -> Exp a -> Exp a)- -> Exp a- -> Acc (Array (sh:.Int) a)- -> Acc (Array (sh:.Int) a)-prescanl f e = P.fst . scanl' f e+prescanl+ :: (Shape sh, Elt a)+ => (Exp a -> Exp a -> Exp a)+ -> Exp a+ -> Acc (Array (sh:.Int) a)+ -> Acc (Array (sh:.Int) a)+prescanl f e = afst . scanl' f e --- | Left-to-right postscan, a variant of 'scanl1' with an initial value. As+-- | Left-to-right post-scan, a variant of 'scanl1' with an initial value. As -- with 'scanl1', the array must not be empty. Denotationally, we have: -- -- > postscanl f e = map (e `f`) . scanl1 f -- -- >>> let vec = fromList (Z:.10) [1..10] -- >>> postscanl (+) 42 (use vec)--- Vector (Z :. 10) [42,43,45,48,52,57,63,70,78,87]+-- Vector (Z :. 10) [43,45,48,52,57,63,70,78,87,97] ---postscanl :: (Shape sh, Elt a)- => (Exp a -> Exp a -> Exp a)- -> Exp a- -> Acc (Array (sh:.Int) a)- -> Acc (Array (sh:.Int) a)+postscanl+ :: (Shape sh, Elt a)+ => (Exp a -> Exp a -> Exp a)+ -> Exp a+ -> Acc (Array (sh:.Int) a)+ -> Acc (Array (sh:.Int) a) postscanl f e = map (e `f`) . scanl1 f --- |Right-to-left prescan (aka exclusive scan). As for 'scan', the first argument must be an--- /associative/ function. Denotationally, we have+-- | Right-to-left pre-scan (aka exclusive scan). As for 'scan', the first+-- argument must be an /associative/ function. Denotationally, we have: ----- > prescanr f e = Prelude.fst . scanr' f e+-- > prescanr f e = afst . scanr' f e ---prescanr :: (Shape sh, Elt a)- => (Exp a -> Exp a -> Exp a)- -> Exp a- -> Acc (Array (sh:.Int) a)- -> Acc (Array (sh:.Int) a)-prescanr f e = P.fst . scanr' f e+prescanr+ :: (Shape sh, Elt a)+ => (Exp a -> Exp a -> Exp a)+ -> Exp a+ -> Acc (Array (sh:.Int) a)+ -> Acc (Array (sh:.Int) a)+prescanr f e = afst . scanr' f e --- |Right-to-left postscan, a variant of 'scanr1' with an initial value. Denotationally, we have+-- | Right-to-left postscan, a variant of 'scanr1' with an initial value.+-- Denotationally, we have: -- -- > postscanr f e = map (e `f`) . scanr1 f ---postscanr :: (Shape sh, Elt a)- => (Exp a -> Exp a -> Exp a)- -> Exp a- -> Acc (Array (sh:.Int) a)- -> Acc (Array (sh:.Int) a)+postscanr+ :: (Shape sh, Elt a)+ => (Exp a -> Exp a -> Exp a)+ -> Exp a+ -> Acc (Array (sh:.Int) a)+ -> Acc (Array (sh:.Int) a) postscanr f e = map (`f` e) . scanr1 f @@ -901,7 +997,7 @@ -- index of each segment. -- seg' = map (+1) seg- tails = zipWith (+) seg . P.fst $ scanl' (+) 0 seg'+ tails = zipWith (+) seg $ prescanl (+) 0 seg' sums = backpermute (lift (indexTail (shape arr') :. length seg)) (\ix -> let sz:.i = unlift ix :: Exp sh :. Exp Int@@ -969,8 +1065,7 @@ -> Acc (Segments i) -> Acc (Array (sh:.Int) e) scanl1Seg f arr seg- = P.snd- . unzip+ = map snd . scanl1 (segmented f) $ zip (replicate (lift (indexTail (shape arr) :. All)) (mkHeadFlags seg)) arr @@ -1103,7 +1198,7 @@ -- reduction values seg' = map (+1) seg- heads = P.fst $ scanl' (+) 0 seg'+ heads = prescanl (+) 0 seg' sums = backpermute (lift (indexTail (shape arr') :. length seg)) (\ix -> let sz:.i = unlift ix :: Exp sh :. Exp Int@@ -1150,8 +1245,7 @@ -> Acc (Segments i) -> Acc (Array (sh:.Int) e) scanr1Seg f arr seg- = P.snd- . unzip+ = map snd . scanr1 (flip (segmented f)) $ zip (replicate (lift (indexTail (shape arr) :. All)) (mkTailFlags seg)) arr @@ -1201,7 +1295,7 @@ = init $ permute (+) zeros (\ix -> index1' (offset ! ix)) ones where- (offset, len) = scanl' (+) 0 seg+ (offset, len) = unlift (scanl' (+) 0 seg) zeros = fill (index1' $ the len + 1) 0 ones = fill (index1 $ size offset) 1 @@ -1216,7 +1310,7 @@ = init $ permute (+) zeros (\ix -> index1' (the len - 1 - offset ! ix)) ones where- (offset, len) = scanr' (+) 0 seg+ (offset, len) = unlift (scanr' (+) 0 seg) zeros = fill (index1' $ the len + 1) 0 ones = fill (index1 $ size offset) 1 @@ -1262,7 +1356,7 @@ | Just Refl <- matchShapeType (undefined::sh) (undefined::DIM1) = a flatten a- = reshape (index1 $ size a) a+ = reshape (index1 (size a)) a -- Enumeration and filling@@ -1270,6 +1364,9 @@ -- | Create an array where all elements are the same value. --+-- >>> let zeros = fill (Z:.10) 0+-- Vector (Z :. 10) [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]+-- fill :: (Shape sh, Elt e) => Exp sh -> Exp e -> Acc (Array sh e) fill sh c = generate sh (const c) @@ -1402,7 +1499,7 @@ | Just Refl <- matchShapeType (undefined::sh) (undefined::Z) = let keep = map p arr- (target, len) = scanl' (+) 0 (map boolToInt keep)+ (target, len) = unlift $ scanl' (+) 0 (map boolToInt keep) prj ix = keep!ix ? ( index1 (target!ix), ignore ) dummy = backpermute (index1 (the len)) id arr result = permute const dummy prj arr@@ -1415,8 +1512,8 @@ = let sz = indexTail (shape arr) keep = map p arr- (target, len) = scanl' (+) 0 (map boolToInt keep)- (offset, valid) = scanl' (+) 0 (flatten len)+ (target, len) = unlift $ scanl' (+) 0 (map boolToInt keep)+ (offset, valid) = unlift $ scanl' (+) 0 (flatten len) prj ix = if keep!ix then index1 $ offset!index1 (toIndex sz (indexTail ix)) + target!ix else ignore@@ -1759,7 +1856,8 @@ -- | Infix version of 'acond'. If the predicate evaluates to 'True', the first -- component of the tuple is returned, else the second. ----- See also: 'ifThenElse'.+-- Enabling the @RebindableSyntax@ extension will allow you to use the standard+-- if-then-else syntax instead. -- infix 0 ?| (?|) :: Arrays a => Exp Bool -> (Acc a, Acc a) -> Acc a@@ -1768,7 +1866,8 @@ -- | An infix version of 'cond'. If the predicate evaluates to 'True', the first -- component of the tuple is returned, else the second. ----- See also: 'ifThenElse'.+-- Enabling the @RebindableSyntax@ extension will allow you to use the standard+-- if-then-else syntax instead. -- infix 0 ? (?) :: Elt t => Exp Bool -> (Exp t, Exp t) -> Exp t@@ -1806,11 +1905,12 @@ -- | Repeatedly apply a function a fixed number of times ---iterate :: forall a. Elt a- => Exp Int- -> (Exp a -> Exp a)- -> Exp a- -> Exp a+iterate+ :: forall a. Elt a+ => Exp Int+ -> (Exp a -> Exp a)+ -> Exp a+ -> Exp a iterate n f z = let step :: (Exp Int, Exp a) -> (Exp Int, Exp a) step (i, acc) = ( i+1, f acc )@@ -1847,6 +1947,7 @@ fst e = let (x, _::Exp b) = unlift e in x -- |Extract the first component of an array pair.+{-# NOINLINE[1] afst #-} afst :: forall a b. (Arrays a, Arrays b) => Acc (a, b) -> Acc a afst a = let (x, _::Acc b) = unlift a in x @@ -1873,34 +1974,36 @@ -- Shapes and indices -- ------------------ --- |The one index for a rank-0 array.+-- | The one index for a rank-0 array. -- index0 :: Exp Z index0 = lift Z --- |Turn an 'Int' expression into a rank-1 indexing expression.+-- | Turn an 'Int' expression into a rank-1 indexing expression. -- index1 :: Elt i => Exp i -> Exp (Z :. i) index1 i = lift (Z :. i) --- |Turn a rank-1 indexing expression into an 'Int' expression.+-- | Turn a rank-1 indexing expression into an 'Int' expression. -- unindex1 :: Elt i => Exp (Z :. i) -> Exp i unindex1 ix = let Z :. i = unlift ix in i -- | Creates a rank-2 index from two Exp Int`s ---index2 :: (Elt i, Slice (Z :. i))- => Exp i- -> Exp i- -> Exp (Z :. i :. i)+index2+ :: (Elt i, Slice (Z :. i))+ => Exp i+ -> Exp i+ -> Exp (Z :. i :. i) index2 i j = lift (Z :. i :. j) -- | Destructs a rank-2 index to an Exp tuple of two Int`s. ---unindex2 :: forall i. (Elt i, Slice (Z :. i))- => Exp (Z :. i :. i)- -> Exp (i, i)+unindex2+ :: forall i. (Elt i, Slice (Z :. i))+ => Exp (Z :. i :. i)+ -> Exp (i, i) unindex2 ix = let Z :. i :. j = unlift ix :: Z :. Exp i :. Exp i in lift (i, j)
Data/Array/Accelerate/Pretty/Graphviz.hs view
@@ -42,9 +42,8 @@ import qualified Data.HashSet as Set -- friends-import Data.Array.Accelerate.AST ( PreOpenAcc(..), PreOpenAfun(..), PreOpenFun(..), PreOpenExp(..), Idx(..) )-import Data.Array.Accelerate.Array.Sugar ( Array, Elt, EltRepr, Tuple(..), Atuple(..), arrays, toElt, strForeign )-import Data.Array.Accelerate.Type ( Boundary(..) )+import Data.Array.Accelerate.AST ( PreOpenAcc(..), PreOpenAfun(..), PreOpenFun(..), PreOpenExp(..), PreBoundary(..), Idx(..) )+import Data.Array.Accelerate.Array.Sugar ( Array, Shape, Elt, Tuple(..), Atuple(..), arrays, toElt, strForeign ) import Data.Array.Accelerate.Error import Data.Array.Accelerate.Trafo.Base import Data.Array.Accelerate.Pretty.Print@@ -249,10 +248,9 @@ Scanr1 f xs -> "scanr1" .$ [ ppF f, ppA xs ] Permute f dfts p xs -> "permute" .$ [ ppF f, ppA dfts, ppF p, ppA xs ] Backpermute sh p xs -> "backpermute" .$ [ ppSh sh, ppF p, ppA xs ]- Stencil sten bndy xs -> "stencil" .$ [ ppF sten, ppB xs bndy, ppA xs ]+ Stencil sten bndy xs -> "stencil" .$ [ ppF sten, ppB bndy, ppA xs ] Stencil2 sten bndy1 acc1 bndy2 acc2- -> "stencil2" .$ [ ppF sten, ppB acc1 bndy1, ppA acc1,- ppB acc2 bndy2, ppA acc2 ]+ -> "stencil2" .$ [ ppF sten, ppB bndy1, ppA acc1, ppB bndy2, ppA acc2 ] Aforeign ff _afun xs -> "aforeign" .$ [ return (PDoc (text (strForeign ff)) []), {- ppAf afun, -} ppA xs ] -- Collect{} -> error "Collect" @@ -312,14 +310,14 @@ PDoc d v <- "Delayed" `fmt` [ ppSh sh, ppF f ] return $ PDoc (parens d) v - ppB :: forall sh e. Elt e- => {-dummy-} DelayedOpenAcc aenv (Array sh e)- -> Boundary (EltRepr e)+ ppB :: forall sh e. (Shape sh, Elt e)+ => PreBoundary DelayedOpenAcc aenv (Array sh e) -> Dot PDoc- ppB _ Clamp = return (PDoc "Clamp" [])- ppB _ Mirror = return (PDoc "Mirror" [])- ppB _ Wrap = return (PDoc "Wrap" [])- ppB _ (Constant e) = return (PDoc (parens $ "Constant" <+> text (show (toElt e :: e))) [])+ ppB Clamp = return (PDoc "Clamp" [])+ ppB Mirror = return (PDoc "Mirror" [])+ ppB Wrap = return (PDoc "Wrap" [])+ ppB (Constant e) = return (PDoc (parens $ "Constant" <+> text (show (toElt e :: e))) [])+ ppB (Function f) = "Function" `fmt` [ ppF f ] ppF :: DelayedFun aenv t -> Dot PDoc ppF = return . uncurry PDoc . (parens . prettyDelayedFun aenv' &&& fvF)
Data/Array/Accelerate/Pretty/Print.hs view
@@ -50,10 +50,9 @@ import Text.PrettyPrint -- friends+import Data.Array.Accelerate.AST hiding ( Val(..), prj ) import Data.Array.Accelerate.Array.Sugar hiding ( tuple ) import Data.Array.Accelerate.Product-import Data.Array.Accelerate.AST hiding ( Val(..), prj )-import Data.Array.Accelerate.Type -- Pretty printing@@ -115,14 +114,14 @@ ppAF :: PreOpenAfun acc aenv f -> Doc ppAF = parens . prettyPreOpenAfun prettyAcc aenv - ppB :: forall sh e. Elt e- => {-dummy-} acc aenv (Array sh e)- -> Boundary (EltRepr e)+ ppB :: forall sh e. (Shape sh, Elt e)+ => PreBoundary acc aenv (Array sh e) -> Doc- ppB _ Clamp = text "Clamp"- ppB _ Mirror = text "Mirror"- ppB _ Wrap = text "Wrap"- ppB _ (Constant e) = parens $ text "Constant" <+> text (show (toElt e :: e))+ ppB Clamp = text "clamp"+ ppB Mirror = text "mirror"+ ppB Wrap = text "wrap"+ ppB (Constant e) = parens $ text "constant" <+> text (show (toElt e :: e))+ ppB (Function f) = ppF f -- pretty print a named array operation with its arguments name .$ docs = wrap $ hang (text name) 2 (sep docs)@@ -171,10 +170,9 @@ pp (Permute f dfts p acc) = "permute" .$ [ ppF f, ppA dfts, ppF p, ppA acc ] pp (Backpermute sh p acc) = "backpermute" .$ [ ppSh sh, ppF p, ppA acc ] pp (Aforeign ff _afun acc) = "aforeign" .$ [ text (strForeign ff), {- ppAf afun, -} ppA acc ]- pp (Stencil sten bndy acc) = "stencil" .$ [ ppF sten, ppB acc bndy, ppA acc ]+ pp (Stencil sten bndy acc) = "stencil" .$ [ ppF sten, ppB bndy, ppA acc ] pp (Stencil2 sten bndy1 acc1 bndy2 acc2)- = "stencil2" .$ [ ppF sten, ppB acc1 bndy1, ppA acc1,- ppB acc2 bndy2, ppA acc2 ]+ = "stencil2" .$ [ ppF sten, ppB bndy1, ppA acc1, ppB bndy2, ppA acc2 ] -- pp (Collect s) = wrap $ hang (text "collect") 2 -- $ encloseSep lbrace rbrace semi@@ -463,6 +461,7 @@ prettyPrim PrimCeiling{} = (False, text "ceiling") prettyPrim PrimAtan2{} = (False, text "atan2") prettyPrim PrimIsNaN{} = (False, text "isNaN")+prettyPrim PrimIsInfinite{} = (False, text "isInfinite") prettyPrim PrimLt{} = (True, text "<") prettyPrim PrimGt{} = (True, text ">") prettyPrim PrimLtEq{} = (True, text "<=")
Data/Array/Accelerate/Product.hs view
@@ -1,7 +1,6 @@ {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-}-{-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-}@@ -29,6 +28,7 @@ TupleIdx(..), IsProduct(..), ProdR(..) ) where+ -- |Type-safe projection indices for tuples. --
Data/Array/Accelerate/Smart.hs view
@@ -28,1604 +28,1924 @@ module Data.Array.Accelerate.Smart ( -- * HOAS AST- Acc(..), PreAcc(..), Exp(..), PreExp(..), Boundary(..), Stencil(..), Level,-- -- * Smart constructors for literals- constant,-- -- * Smart constructors and destructors for tuples- tup2, tup3, tup4, tup5, tup6, tup7, tup8, tup9, tup10, tup11, tup12, tup13, tup14, tup15,- untup2, untup3, untup4, untup5, untup6, untup7, untup8, untup9, untup10, untup11, untup12, untup13, untup14, untup15,-- atup2, atup3, atup4, atup5, atup6, atup7, atup8, atup9, atup10, atup11, atup12, atup13, atup14, atup15,- unatup2, unatup3, unatup4, unatup5, unatup6, unatup7, unatup8, unatup9, unatup10, unatup11, unatup12, unatup13, unatup14, unatup15,-- -- * Smart constructors for constants- mkMinBound, mkMaxBound, mkPi,- mkSin, mkCos, mkTan,- mkAsin, mkAcos, mkAtan,- mkSinh, mkCosh, mkTanh,- mkAsinh, mkAcosh, mkAtanh,- mkExpFloating, mkSqrt, mkLog,- mkFPow, mkLogBase,- mkTruncate, mkRound, mkFloor, mkCeiling,- mkAtan2,-- -- * Smart constructors for primitive functions- mkAdd, mkSub, mkMul, mkNeg, mkAbs, mkSig, mkQuot, mkRem, mkQuotRem, mkIDiv, mkMod, mkDivMod,- mkBAnd, mkBOr, mkBXor, mkBNot, mkBShiftL, mkBShiftR, mkBRotateL, mkBRotateR, mkPopCount, mkCountLeadingZeros, mkCountTrailingZeros,- mkFDiv, mkRecip, mkLt, mkGt, mkLtEq, mkGtEq, mkEq, mkNEq, mkMax, mkMin,- mkLAnd, mkLOr, mkLNot, mkIsNaN,-- -- * Smart constructors for type coercion functions- mkOrd, mkChr, mkBoolToInt, mkFromIntegral, mkToFloating, mkBitcast, mkUnsafeCoerce,-- -- * Auxiliary functions- ($$), ($$$), ($$$$), ($$$$$),-- -- Debugging- showPreAccOp, showPreExpOp,--) where---- standard library-import Prelude hiding ( exp )-import Data.List-import Data.Typeable---- friends-import Data.Array.Accelerate.Type-import Data.Array.Accelerate.Array.Sugar-import Data.Array.Accelerate.Product-import Data.Array.Accelerate.AST hiding ( PreOpenAcc(..), OpenAcc(..), Acc- , PreOpenExp(..), OpenExp, PreExp, Exp- , Stencil(..)- , showPreAccOp, showPreExpOp )-import qualified Data.Array.Accelerate.AST as AST---- Array computations--- ---------------------- | Accelerate is an /embedded language/ that distinguishes between vanilla--- arrays (e.g. in Haskell memory on the CPU) and embedded arrays (e.g. in--- device memory on a GPU), as well as the computations on both of these. Since--- Accelerate is an embedded language, programs written in Accelerate are not--- compiled by the Haskell compiler (GHC). Rather, each Accelerate backend is--- a /runtime compiler/ which generates and executes parallel SIMD code of the--- target language at application /runtime/.------ The type constructor 'Acc' represents embedded collective array operations.--- A term of type @Acc a@ is an Accelerate program which, once executed, will--- produce a value of type 'a' (an 'Array' or a tuple of 'Arrays'). Collective--- operations of type @Acc a@ comprise many /scalar expressions/, wrapped in--- type constructor 'Exp', which will be executed in parallel. Although--- collective operations comprise many scalar operations executed in parallel,--- scalar operations /cannot/ initiate new collective operations: this--- stratification between scalar operations in 'Exp' and array operations in--- 'Acc' helps statically exclude /nested data parallelism/, which is difficult--- to execute efficiently on constrained hardware such as GPUs.------ For example, to compute a vector dot product we could write:------ > dotp :: Num a => Vector a -> Vector a -> Acc (Scalar a)--- > dotp xs ys =--- > let--- > xs' = use xs--- > ys' = use ys--- > in--- > fold (+) 0 ( zipWith (*) xs' ys' )------ The function @dotp@ consumes two one-dimensional arrays ('Vector's) of--- values, and produces a single ('Scalar') result as output. As the return type--- is wrapped in the type 'Acc', we see that it is an embedded Accelerate--- computation - it will be evaluated in the /object/ language of dynamically--- generated parallel code, rather than the /meta/ language of vanilla Haskell.------ As the arguments to @dotp@ are plain Haskell arrays, to make these available--- to Accelerate computations they must be embedded with the--- 'Data.Array.Accelerate.Language.use' function.------ An Accelerate backend is used to evaluate the embedded computation and return--- the result back to vanilla Haskell. Calling the 'run' function of a backend--- will generate code for the target architecture, compile, and execute it. For--- example, the following backends are available:------ * <http://hackage.haskell.org/package/accelerate-llvm-native accelerate-llvm-native>: for execution on multicore CPUs--- * <http://hackage.haskell.org/package/accelerate-llvm-ptx accelerate-llvm-ptx>: for execution on NVIDIA CUDA-capable GPUs------ See also 'Exp', which encapsulates embedded /scalar/ computations.------ [/Fusion:/]------ Array computations of type 'Acc' will be subject to /array fusion/;--- Accelerate will combine individual 'Acc' computations into a single--- computation, which reduces the number of traversals over the input data and--- thus improves performance. As such, it is often useful to have some intuition--- on when fusion should occur.------ The main idea is to first partition array operations into two categories:------ 1. Element-wise operations, such as 'Data.Array.Accelerate.map',--- 'Data.Array.Accelerate.generate', and--- 'Data.Array.Accelerate.backpermute'. Each element of these operations--- can be computed independently of all others.------ 2. Collective operations such as 'Data.Array.Accelerate.fold',--- 'Data.Array.Accelerate.scanl', and 'Data.Array.Accelerate.stencil'. To--- compute each output element of these operations requires reading--- multiple elements from the input array(s).------ Element-wise operations fuse together whenever the consumer operation uses--- a single element of the input array. Element-wise operations can both fuse--- their inputs into themselves, as well be fused into later operations. Both--- these examples should fuse into a single loop:------ > map -> reverse -> reshape -> map -> map------ > map -> backpermute ->--- > zipWith -> map--- > generate ->------ If the consumer operation uses more than one element of the input array--- (typically, via 'Data.Array.Accelerate.generate' indexing an array multiple--- times), then the input array will be completely evaluated first; no fusion--- occurs in this case, because fusing the first operation into the second--- implies duplicating work.------ On the other hand, collective operations can fuse their input arrays into--- themselves, but on output always evaluate to an array; collective operations--- will not be fused into a later step. For example:------ > use ->--- > zipWith -> fold |-> map--- > generate ->------ Here the element-wise sequence ('Data.Array.Accelerate.use'--- + 'Data.Array.Accelerate.generate' + 'Data.Array.Accelerate.zipWith') will--- fuse into a single operation, which then fuses into the collective--- 'Data.Array.Accelerate.fold' operation. At this point in the program the--- 'Data.Array.Accelerate.fold' must now be evaluated. In the final step the--- 'Data.Array.Accelerate.map' reads in the array produced by--- 'Data.Array.Accelerate.fold'. As there is no fusion between the--- 'Data.Array.Accelerate.fold' and 'Data.Array.Accelerate.map' steps, this--- program consists of two "loops"; one for the 'Data.Array.Accelerate.use'--- + 'Data.Array.Accelerate.generate' + 'Data.Array.Accelerate.zipWith'--- + 'Data.Array.Accelerate.fold' step, and one for the final--- 'Data.Array.Accelerate.map' step.------ You can see how many operations will be executed in the fused program by--- 'Show'-ing the 'Acc' program, or by using the debugging option @-ddump-dot@--- to save the program as a graphviz DOT file.------ As a special note, the operations 'Data.Array.Accelerate.unzip' and--- 'Data.Array.Accelerate.reshape', when applied to a real array, are executed--- in constant time, so in this situation these operations will not be fused.------ [/Tips:/]------ * Since 'Acc' represents embedded computations that will only be executed--- when evaluated by a backend, we can programatically generate these--- computations using the meta language Haskell; for example, unrolling loops--- or embedding input values into the generated code.------ * It is usually best to keep all intermediate computations in 'Acc', and--- only 'run' the computation at the very end to produce the final result.--- This enables optimisations between intermediate results (e.g. array--- fusion) and, if the target architecture has a separate memory space as is--- the case of GPUs, to prevent excessive data transfers.----newtype Acc a = Acc (PreAcc Acc Exp a)-deriving instance Typeable Acc----- The level of lambda-bound variables. The root has level 0; then it increases with each bound--- variable — i.e., it is the same as the size of the environment at the defining occurrence.----type Level = Int---- | Array-valued collective computations without a recursive knot----data PreAcc acc exp as where- -- Needed for conversion to de Bruijn form- Atag :: Arrays as- => Level -- environment size at defining occurrence- -> PreAcc acc exp as-- Pipe :: (Arrays as, Arrays bs, Arrays cs)- => (Acc as -> acc bs)- -> (Acc bs -> acc cs)- -> acc as- -> PreAcc acc exp cs-- Aforeign :: (Arrays as, Arrays bs, Foreign asm)- => asm (as -> bs)- -> (Acc as -> Acc bs)- -> acc as- -> PreAcc acc exp bs-- Acond :: Arrays as- => exp Bool- -> acc as- -> acc as- -> PreAcc acc exp as-- Awhile :: Arrays arrs- => (Acc arrs -> acc (Scalar Bool))- -> (Acc arrs -> acc arrs)- -> acc arrs- -> PreAcc acc exp arrs-- Atuple :: (Arrays arrs, IsAtuple arrs)- => Atuple acc (TupleRepr arrs)- -> PreAcc acc exp arrs-- Aprj :: (Arrays arrs, IsAtuple arrs, Arrays a)- => TupleIdx (TupleRepr arrs) a- -> acc arrs- -> PreAcc acc exp a-- Use :: Arrays arrs- => arrs- -> PreAcc acc exp arrs-- Unit :: Elt e- => exp e- -> PreAcc acc exp (Scalar e)-- Generate :: (Shape sh, Elt e)- => exp sh- -> (Exp sh -> exp e)- -> PreAcc acc exp (Array sh e)-- Reshape :: (Shape sh, Shape sh', Elt e)- => exp sh- -> acc (Array sh' e)- -> PreAcc acc exp (Array sh e)-- Replicate :: (Slice slix, Elt e)- => exp slix- -> acc (Array (SliceShape slix) e)- -> PreAcc acc exp (Array (FullShape slix) e)-- Slice :: (Slice slix, Elt e)- => acc (Array (FullShape slix) e)- -> exp slix- -> PreAcc acc exp (Array (SliceShape slix) e)-- Map :: (Shape sh, Elt e, Elt e')- => (Exp e -> exp e')- -> acc (Array sh e)- -> PreAcc acc exp (Array sh e')-- ZipWith :: (Shape sh, Elt e1, Elt e2, Elt e3)- => (Exp e1 -> Exp e2 -> exp e3)- -> acc (Array sh e1)- -> acc (Array sh e2)- -> PreAcc acc exp (Array sh e3)-- Fold :: (Shape sh, Elt e)- => (Exp e -> Exp e -> exp e)- -> exp e- -> acc (Array (sh:.Int) e)- -> PreAcc acc exp (Array sh e)-- Fold1 :: (Shape sh, Elt e)- => (Exp e -> Exp e -> exp e)- -> acc (Array (sh:.Int) e)- -> PreAcc acc exp (Array sh e)-- FoldSeg :: (Shape sh, Elt e, Elt i, IsIntegral i)- => (Exp e -> Exp e -> exp e)- -> exp e- -> acc (Array (sh:.Int) e)- -> acc (Segments i)- -> PreAcc acc exp (Array (sh:.Int) e)-- Fold1Seg :: (Shape sh, Elt e, Elt i, IsIntegral i)- => (Exp e -> Exp e -> exp e)- -> acc (Array (sh:.Int) e)- -> acc (Segments i)- -> PreAcc acc exp (Array (sh:.Int) e)-- Scanl :: (Shape sh, Elt e)- => (Exp e -> Exp e -> exp e)- -> exp e- -> acc (Array (sh :. Int) e)- -> PreAcc acc exp (Array (sh :. Int) e)-- Scanl' :: (Shape sh, Elt e)- => (Exp e -> Exp e -> exp e)- -> exp e- -> acc (Array (sh :. Int) e)- -> PreAcc acc exp (Array (sh :. Int) e, Array sh e)-- Scanl1 :: (Shape sh, Elt e)- => (Exp e -> Exp e -> exp e)- -> acc (Array (sh :. Int) e)- -> PreAcc acc exp (Array (sh :. Int) e)-- Scanr :: (Shape sh, Elt e)- => (Exp e -> Exp e -> exp e)- -> exp e- -> acc (Array (sh :. Int) e)- -> PreAcc acc exp (Array (sh :. Int) e)-- Scanr' :: (Shape sh, Elt e)- => (Exp e -> Exp e -> exp e)- -> exp e- -> acc (Array (sh :. Int) e)- -> PreAcc acc exp (Array (sh :. Int) e, Array sh e)-- Scanr1 :: (Shape sh, Elt e)- => (Exp e -> Exp e -> exp e)- -> acc (Array (sh :. Int) e)- -> PreAcc acc exp (Array (sh :. Int) e)-- Permute :: (Shape sh, Shape sh', Elt e)- => (Exp e -> Exp e -> exp e)- -> acc (Array sh' e)- -> (Exp sh -> exp sh')- -> acc (Array sh e)- -> PreAcc acc exp (Array sh' e)-- Backpermute :: (Shape sh, Shape sh', Elt e)- => exp sh'- -> (Exp sh' -> exp sh)- -> acc (Array sh e)- -> PreAcc acc exp (Array sh' e)-- Stencil :: (Shape sh, Elt a, Elt b, Stencil sh a stencil)- => (stencil -> exp b)- -> Boundary a- -> acc (Array sh a)- -> PreAcc acc exp (Array sh b)-- Stencil2 :: (Shape sh, Elt a, Elt b, Elt c,- Stencil sh a stencil1, Stencil sh b stencil2)- => (stencil1 -> stencil2 -> exp c)- -> Boundary a- -> acc (Array sh a)- -> Boundary b- -> acc (Array sh b)- -> PreAcc acc exp (Array sh c)-- -- Collect :: Arrays arrs- -- => seq arrs- -- -> PreAcc acc seq exp arrs---{---data PreSeq acc seq exp arrs where- -- Convert the given Haskell-list of arrays to a sequence.- StreamIn :: Arrays a- => [a]- -> PreSeq acc seq exp [a]-- -- Convert the given array to a sequence.- -- Example:- -- slix = Z :. All :. Split :. All :. All :. Split- -- ^ ^ ^ ^ ^- -- | \ / / |- -- | \___/______/_______ Iteration space.- -- | / /- -- Element________/______/- -- shape.- --- ToSeq :: ( Elt e- , Slice slix- , Division slsix- , DivisionSlice slsix ~ slix- , Typeable (FullShape slix)- , Typeable (SliceShape slix)- )- => slsix- -> acc (Array (FullShape slix) e)- -> PreSeq acc seq exp [Array (SliceShape slix) e]-- -- Apply the given the given function to all elements of the given sequence.- MapSeq :: (Arrays a, Arrays b)- => (Acc a -> acc b)- -> seq [a]- -> PreSeq acc seq exp [b]-- -- Apply a given binary function pairwise to all elements of the given sequences.- -- The length of the result is the length of the shorter of the two argument- -- arrays.- ZipWithSeq :: (Arrays a, Arrays b, Arrays c)- => (Acc a -> Acc b -> acc c)- -> seq [a]- -> seq [b]- -> PreSeq acc seq exp [c]-- -- ScanSeq (+) a0 x. Scan a sequence x by combining each element- -- using the given binary operation (+). (+) must be associative:- --- -- Forall a b c. (a + b) + c = a + (b + c),- --- -- and a0 must be the identity element for (+):- --- -- Forall a. a0 + a = a = a + a0.- --- ScanSeq :: Elt a- => (Exp a -> Exp a -> exp a)- -> exp a- -> seq [Scalar a]- -> PreSeq acc seq exp [Scalar a]-- -- FoldSeq (+) a0 x. Fold a sequence x by combining each element- -- using the given binary operation (+). (+) must be associative:- --- -- Forall a b c. (a + b) + c = a + (b + c),- --- -- and a0 must be the identity element for (+):- --- -- Forall a. a0 + a = a = a + a0.- --- FoldSeq :: Elt a- => (Exp a -> Exp a -> exp a)- -> exp a- -> seq [Scalar a]- -> PreSeq acc seq exp (Scalar a)-- -- FoldSeqFlatten f a0 x. A specialized version of FoldSeqAct- -- where reduction with the companion operator corresponds to- -- flattening. f must be semi-associative, with vecotor append (++)- -- as the companion operator:- --- -- Forall b s1 a2 sh2 a2.- -- f (f b sh1 a1) sh2 a2 = f b (sh1 ++ sh2) (a1 ++ a2).- --- -- It is common to ignore the shape vectors, yielding the usual- -- semi-associativity law:- --- -- f b a _ = b + a,- --- -- for some (+) satisfying:- --- -- Forall b a1 a2. (b + a1) + a2 = b + (a1 ++ a2).- --- FoldSeqFlatten :: (Arrays a, Shape sh, Elt e)- => (Acc a -> Acc (Vector sh) -> Acc (Vector e) -> acc a)- -> acc a- -> seq [Array sh e]- -> PreSeq acc seq exp a-- -- Tuple up the results of a sequence computation. Note that the Arrays- -- constraint requires that the elements of the tuple are Arrays, not- -- streams ([]).- Stuple :: (Arrays arrs, IsAtuple arrs)- => Atuple (seq) (TupleRepr arrs)- -> PreSeq acc seq exp arrs---- |Array-valued sequence computations----newtype Seq a = Seq (PreSeq Acc Seq Exp a)--deriving instance Typeable Seq---}----- Embedded expressions of the surface language--- ------------------------------------------------ HOAS expressions mirror the constructors of 'AST.OpenExp', but with the 'Tag'--- constructor instead of variables in the form of de Bruijn indices. Moreover,--- HOAS expression use n-tuples and the type class 'Elt' to constrain element--- types, whereas 'AST.OpenExp' uses nested pairs and the GADT 'TupleType'.------- | The type 'Exp' represents embedded scalar expressions. The collective--- operations of Accelerate 'Acc' consist of many scalar expressions executed in--- data-parallel.------ Note that scalar expressions can not initiate new collective operations:--- doing so introduces /nested data parallelism/, which is difficult to execute--- efficiently on constrained hardware such as GPUs, and is thus currently--- unsupported.----newtype Exp t = Exp (PreExp Acc Exp t)--deriving instance Typeable Exp---- | Scalar expressions to parametrise collective array operations, themselves parameterised over--- the type of collective array operations.----data PreExp acc exp t where- -- Needed for conversion to de Bruijn form- Tag :: Elt t- => Level -- environment size at defining occurrence- -> PreExp acc exp t-- -- All the same constructors as 'AST.Exp'- Const :: Elt t- => t- -> PreExp acc exp t-- Tuple :: (Elt t, IsTuple t)- => Tuple exp (TupleRepr t)- -> PreExp acc exp t-- Prj :: (Elt t, IsTuple t, Elt e)- => TupleIdx (TupleRepr t) e- -> exp t- -> PreExp acc exp e-- IndexNil :: PreExp acc exp Z-- IndexCons :: (Slice sl, Elt a)- => exp sl- -> exp a- -> PreExp acc exp (sl:.a)-- IndexHead :: (Slice sl, Elt a)- => exp (sl:.a)- -> PreExp acc exp a-- IndexTail :: (Slice sl, Elt a)- => exp (sl:.a)- -> PreExp acc exp sl-- IndexAny :: Shape sh- => PreExp acc exp (Any sh)-- ToIndex :: Shape sh- => exp sh- -> exp sh- -> PreExp acc exp Int-- FromIndex :: Shape sh- => exp sh- -> exp Int- -> PreExp acc exp sh-- Cond :: Elt t- => exp Bool- -> exp t- -> exp t- -> PreExp acc exp t-- While :: Elt t- => (Exp t -> exp Bool)- -> (Exp t -> exp t)- -> exp t- -> PreExp acc exp t-- PrimConst :: Elt t- => PrimConst t- -> PreExp acc exp t-- PrimApp :: (Elt a, Elt r)- => PrimFun (a -> r)- -> exp a- -> PreExp acc exp r-- Index :: (Shape sh, Elt t)- => acc (Array sh t)- -> exp sh- -> PreExp acc exp t-- LinearIndex :: (Shape sh, Elt t)- => acc (Array sh t)- -> exp Int- -> PreExp acc exp t-- Shape :: (Shape sh, Elt e)- => acc (Array sh e)- -> PreExp acc exp sh-- ShapeSize :: Shape sh- => exp sh- -> PreExp acc exp Int-- Intersect :: Shape sh- => exp sh- -> exp sh- -> PreExp acc exp sh-- Union :: Shape sh- => exp sh- -> exp sh- -> PreExp acc exp sh-- Foreign :: (Elt x, Elt y, Foreign asm)- => asm (x -> y)- -> (Exp x -> Exp y) -- RCE: Using Exp instead of exp to aid in sharing recovery.- -> exp x- -> PreExp acc exp y----- Smart constructors and destructors for array tuples--- -----------------------------------------------------atup2 :: (Arrays a, Arrays b) => (Acc a, Acc b) -> Acc (a, b)-atup2 (a, b) = Acc $ Atuple (NilAtup `SnocAtup` a `SnocAtup` b)--atup3 :: (Arrays a, Arrays b, Arrays c) => (Acc a, Acc b, Acc c) -> Acc (a, b, c)-atup3 (a, b, c) = Acc $ Atuple (NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c)--atup4 :: (Arrays a, Arrays b, Arrays c, Arrays d)- => (Acc a, Acc b, Acc c, Acc d) -> Acc (a, b, c, d)-atup4 (a, b, c, d)- = Acc $ Atuple (NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d)--atup5 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e)- => (Acc a, Acc b, Acc c, Acc d, Acc e) -> Acc (a, b, c, d, e)-atup5 (a, b, c, d, e)- = Acc $ Atuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e--atup6 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f)- => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f) -> Acc (a, b, c, d, e, f)-atup6 (a, b, c, d, e, f)- = Acc $ Atuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c- `SnocAtup` d `SnocAtup` e `SnocAtup` f--atup7 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g)- => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g)- -> Acc (a, b, c, d, e, f, g)-atup7 (a, b, c, d, e, f, g)- = Acc $ Atuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c- `SnocAtup` d `SnocAtup` e `SnocAtup` f `SnocAtup` g--atup8 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h)- => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h)- -> Acc (a, b, c, d, e, f, g, h)-atup8 (a, b, c, d, e, f, g, h)- = Acc $ Atuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d- `SnocAtup` e `SnocAtup` f `SnocAtup` g `SnocAtup` h--atup9 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i)- => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i)- -> Acc (a, b, c, d, e, f, g, h, i)-atup9 (a, b, c, d, e, f, g, h, i)- = Acc $ Atuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d- `SnocAtup` e `SnocAtup` f `SnocAtup` g `SnocAtup` h `SnocAtup` i--atup10 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j)- => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j)- -> Acc (a, b, c, d, e, f, g, h, i, j)-atup10 (a, b, c, d, e, f, g, h, i, j)- = Acc $ Atuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e- `SnocAtup` f `SnocAtup` g `SnocAtup` h `SnocAtup` i `SnocAtup` j--atup11 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k)- => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k)- -> Acc (a, b, c, d, e, f, g, h, i, j, k)-atup11 (a, b, c, d, e, f, g, h, i, j, k)- = Acc $ Atuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e- `SnocAtup` f `SnocAtup` g `SnocAtup` h `SnocAtup` i `SnocAtup` j `SnocAtup` k--atup12 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l)- => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k, Acc l)- -> Acc (a, b, c, d, e, f, g, h, i, j, k, l)-atup12 (a, b, c, d, e, f, g, h, i, j, k, l)- = Acc $ Atuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e `SnocAtup` f- `SnocAtup` g `SnocAtup` h `SnocAtup` i `SnocAtup` j `SnocAtup` k `SnocAtup` l--atup13 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m)- => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k, Acc l, Acc m)- -> Acc (a, b, c, d, e, f, g, h, i, j, k, l, m)-atup13 (a, b, c, d, e, f, g, h, i, j, k, l, m)- = Acc $ Atuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e `SnocAtup` f- `SnocAtup` g `SnocAtup` h `SnocAtup` i `SnocAtup` j `SnocAtup` k `SnocAtup` l `SnocAtup` m--atup14 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m, Arrays n)- => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k, Acc l, Acc m, Acc n)- -> Acc (a, b, c, d, e, f, g, h, i, j, k, l, m, n)-atup14 (a, b, c, d, e, f, g, h, i, j, k, l, m, n)- = Acc $ Atuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e `SnocAtup` f `SnocAtup` g- `SnocAtup` h `SnocAtup` i `SnocAtup` j `SnocAtup` k `SnocAtup` l `SnocAtup` m `SnocAtup` n--atup15 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m, Arrays n, Arrays o)- => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k, Acc l, Acc m, Acc n, Acc o)- -> Acc (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)-atup15 (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)- = Acc $ Atuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e `SnocAtup` f `SnocAtup` g- `SnocAtup` h `SnocAtup` i `SnocAtup` j `SnocAtup` k `SnocAtup` l `SnocAtup` m `SnocAtup` n `SnocAtup` o--unatup2 :: (Arrays a, Arrays b) => Acc (a, b) -> (Acc a, Acc b)-unatup2 e =- ( Acc $ SuccTupIdx ZeroTupIdx `Aprj` e- , Acc $ ZeroTupIdx `Aprj` e )--unatup3 :: (Arrays a, Arrays b, Arrays c) => Acc (a, b, c) -> (Acc a, Acc b, Acc c)-unatup3 e =- ( Acc $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Aprj` e- , Acc $ SuccTupIdx ZeroTupIdx `Aprj` e- , Acc $ ZeroTupIdx `Aprj` e )--unatup4- :: (Arrays a, Arrays b, Arrays c, Arrays d)- => Acc (a, b, c, d) -> (Acc a, Acc b, Acc c, Acc d)-unatup4 e =- ( Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Aprj` e- , Acc $ SuccTupIdx ZeroTupIdx `Aprj` e- , Acc $ ZeroTupIdx `Aprj` e )--unatup5- :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e)- => Acc (a, b, c, d, e) -> (Acc a, Acc b, Acc c, Acc d, Acc e)-unatup5 e =- ( Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Aprj` e- , Acc $ SuccTupIdx ZeroTupIdx `Aprj` e- , Acc $ ZeroTupIdx `Aprj` e )--unatup6- :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f)- => Acc (a, b, c, d, e, f) -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f)-unatup6 e =- ( Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Aprj` e- , Acc $ SuccTupIdx ZeroTupIdx `Aprj` e- , Acc $ ZeroTupIdx `Aprj` e )--unatup7- :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g)- => Acc (a, b, c, d, e, f, g) -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g)-unatup7 e =- ( Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Aprj` e- , Acc $ SuccTupIdx ZeroTupIdx `Aprj` e- , Acc $ ZeroTupIdx `Aprj` e )--unatup8- :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h)- => Acc (a, b, c, d, e, f, g, h) -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h)-unatup8 e =- ( Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Aprj` e- , Acc $ SuccTupIdx ZeroTupIdx `Aprj` e- , Acc $ ZeroTupIdx `Aprj` e )--unatup9- :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i)- => Acc (a, b, c, d, e, f, g, h, i) -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i)-unatup9 e =- ( Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Aprj` e- , Acc $ SuccTupIdx ZeroTupIdx `Aprj` e- , Acc $ ZeroTupIdx `Aprj` e )--unatup10 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j)- => Acc (a, b, c, d, e, f, g, h, i, j) -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j)-unatup10 e =- ( Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Aprj` e- , Acc $ SuccTupIdx ZeroTupIdx `Aprj` e- , Acc $ ZeroTupIdx `Aprj` e)--unatup11 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k)- => Acc (a, b, c, d, e, f, g, h, i, j, k) -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k)-unatup11 e =- ( Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Aprj` e- , Acc $ SuccTupIdx ZeroTupIdx `Aprj` e- , Acc $ ZeroTupIdx `Aprj` e)--unatup12 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l)- => Acc (a, b, c, d, e, f, g, h, i, j, k, l) -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k, Acc l)-unatup12 e =- ( Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Aprj` e- , Acc $ SuccTupIdx ZeroTupIdx `Aprj` e- , Acc $ ZeroTupIdx `Aprj` e)--unatup13 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m)- => Acc (a, b, c, d, e, f, g, h, i, j, k, l, m) -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k, Acc l, Acc m)-unatup13 e =- ( Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Aprj` e- , Acc $ SuccTupIdx ZeroTupIdx `Aprj` e- , Acc $ ZeroTupIdx `Aprj` e)--unatup14 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m, Arrays n)- => Acc (a, b, c, d, e, f, g, h, i, j, k, l, m, n) -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k, Acc l, Acc m, Acc n)-unatup14 e =- ( Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Aprj` e- , Acc $ SuccTupIdx ZeroTupIdx `Aprj` e- , Acc $ ZeroTupIdx `Aprj` e)--unatup15 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m, Arrays n, Arrays o)- => Acc (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k, Acc l, Acc m, Acc n, Acc o)-unatup15 e =- ( Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Aprj` e- , Acc $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Aprj` e- , Acc $ SuccTupIdx ZeroTupIdx `Aprj` e- , Acc $ ZeroTupIdx `Aprj` e)------ Smart constructors for stencil reification--- ---------------------------------------------- Stencil reification------ In the AST representation, we turn the stencil type from nested tuples of Accelerate expressions--- into an Accelerate expression whose type is a tuple nested in the same manner. This enables us--- to represent the stencil function as a unary function (which also only needs one de Bruijn--- index). The various positions in the stencil are accessed via tuple indices (i.e., projections).--class (Elt (StencilRepr sh stencil), AST.Stencil sh a (StencilRepr sh stencil))- => Stencil sh a stencil where- type StencilRepr sh stencil :: *- stencilPrj :: sh{-dummy-} -> a{-dummy-} -> Exp (StencilRepr sh stencil) -> stencil---- DIM1-instance Elt e => Stencil DIM1 e (Exp e, Exp e, Exp e) where- type StencilRepr DIM1 (Exp e, Exp e, Exp e)- = (e, e, e)- stencilPrj _ _ s = (Exp $ Prj tix2 s,- Exp $ Prj tix1 s,- Exp $ Prj tix0 s)-instance Elt e => Stencil DIM1 e (Exp e, Exp e, Exp e, Exp e, Exp e) where- type StencilRepr DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e)- = (e, e, e, e, e)- stencilPrj _ _ s = (Exp $ Prj tix4 s,- Exp $ Prj tix3 s,- Exp $ Prj tix2 s,- Exp $ Prj tix1 s,- Exp $ Prj tix0 s)-instance Elt e => Stencil DIM1 e (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e) where- type StencilRepr DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e)- = (e, e, e, e, e, e, e)- stencilPrj _ _ s = (Exp $ Prj tix6 s,- Exp $ Prj tix5 s,- Exp $ Prj tix4 s,- Exp $ Prj tix3 s,- Exp $ Prj tix2 s,- Exp $ Prj tix1 s,- Exp $ Prj tix0 s)-instance Elt e => Stencil DIM1 e (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e)- where- type StencilRepr DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e)- = (e, e, e, e, e, e, e, e, e)- stencilPrj _ _ s = (Exp $ Prj tix8 s,- Exp $ Prj tix7 s,- Exp $ Prj tix6 s,- Exp $ Prj tix5 s,- Exp $ Prj tix4 s,- Exp $ Prj tix3 s,- Exp $ Prj tix2 s,- Exp $ Prj tix1 s,- Exp $ Prj tix0 s)---- DIM(n+1)-instance (Stencil (sh:.Int) a row2,- Stencil (sh:.Int) a row1,- Stencil (sh:.Int) a row0) => Stencil (sh:.Int:.Int) a (row2, row1, row0) where- type StencilRepr (sh:.Int:.Int) (row2, row1, row0)- = (StencilRepr (sh:.Int) row2, StencilRepr (sh:.Int) row1, StencilRepr (sh:.Int) row0)- stencilPrj _ a s = (stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix2 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix1 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix0 s))-instance (Stencil (sh:.Int) a row1,- Stencil (sh:.Int) a row2,- Stencil (sh:.Int) a row3,- Stencil (sh:.Int) a row4,- Stencil (sh:.Int) a row5) => Stencil (sh:.Int:.Int) a (row1, row2, row3, row4, row5) where- type StencilRepr (sh:.Int:.Int) (row1, row2, row3, row4, row5)- = (StencilRepr (sh:.Int) row1, StencilRepr (sh:.Int) row2, StencilRepr (sh:.Int) row3,- StencilRepr (sh:.Int) row4, StencilRepr (sh:.Int) row5)- stencilPrj _ a s = (stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix4 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix3 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix2 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix1 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix0 s))-instance (Stencil (sh:.Int) a row1,- Stencil (sh:.Int) a row2,- Stencil (sh:.Int) a row3,- Stencil (sh:.Int) a row4,- Stencil (sh:.Int) a row5,- Stencil (sh:.Int) a row6,- Stencil (sh:.Int) a row7)- => Stencil (sh:.Int:.Int) a (row1, row2, row3, row4, row5, row6, row7) where- type StencilRepr (sh:.Int:.Int) (row1, row2, row3, row4, row5, row6, row7)- = (StencilRepr (sh:.Int) row1, StencilRepr (sh:.Int) row2, StencilRepr (sh:.Int) row3,- StencilRepr (sh:.Int) row4, StencilRepr (sh:.Int) row5, StencilRepr (sh:.Int) row6,- StencilRepr (sh:.Int) row7)- stencilPrj _ a s = (stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix6 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix5 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix4 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix3 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix2 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix1 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix0 s))-instance (Stencil (sh:.Int) a row1,- Stencil (sh:.Int) a row2,- Stencil (sh:.Int) a row3,- Stencil (sh:.Int) a row4,- Stencil (sh:.Int) a row5,- Stencil (sh:.Int) a row6,- Stencil (sh:.Int) a row7,- Stencil (sh:.Int) a row8,- Stencil (sh:.Int) a row9)- => Stencil (sh:.Int:.Int) a (row1, row2, row3, row4, row5, row6, row7, row8, row9) where- type StencilRepr (sh:.Int:.Int) (row1, row2, row3, row4, row5, row6, row7, row8, row9)- = (StencilRepr (sh:.Int) row1, StencilRepr (sh:.Int) row2, StencilRepr (sh:.Int) row3,- StencilRepr (sh:.Int) row4, StencilRepr (sh:.Int) row5, StencilRepr (sh:.Int) row6,- StencilRepr (sh:.Int) row7, StencilRepr (sh:.Int) row8, StencilRepr (sh:.Int) row9)- stencilPrj _ a s = (stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix8 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix7 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix6 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix5 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix4 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix3 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix2 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix1 s),- stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix0 s))---- Auxiliary tuple index constants----tix0 :: TupleIdx (t, s0) s0-tix0 = ZeroTupIdx--tix1 :: TupleIdx ((t, s1), s0) s1-tix1 = SuccTupIdx tix0--tix2 :: TupleIdx (((t, s2), s1), s0) s2-tix2 = SuccTupIdx tix1--tix3 :: TupleIdx ((((t, s3), s2), s1), s0) s3-tix3 = SuccTupIdx tix2--tix4 :: TupleIdx (((((t, s4), s3), s2), s1), s0) s4-tix4 = SuccTupIdx tix3--tix5 :: TupleIdx ((((((t, s5), s4), s3), s2), s1), s0) s5-tix5 = SuccTupIdx tix4--tix6 :: TupleIdx (((((((t, s6), s5), s4), s3), s2), s1), s0) s6-tix6 = SuccTupIdx tix5--tix7 :: TupleIdx ((((((((t, s7), s6), s5), s4), s3), s2), s1), s0) s7-tix7 = SuccTupIdx tix6--tix8 :: TupleIdx (((((((((t, s8), s7), s6), s5), s4), s3), s2), s1), s0) s8-tix8 = SuccTupIdx tix7--{----- Smart constructors for array tuples in sequence computations--- -----------------------------------------------------stup2 :: (Arrays a, Arrays b) => (Seq a, Seq b) -> Seq (a, b)-stup2 (a, b) = Seq $ Stuple (NilAtup `SnocAtup` a `SnocAtup` b)--stup3 :: (Arrays a, Arrays b, Arrays c) => (Seq a, Seq b, Seq c) -> Seq (a, b, c)-stup3 (a, b, c) = Seq $ Stuple (NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c)--stup4 :: (Arrays a, Arrays b, Arrays c, Arrays d)- => (Seq a, Seq b, Seq c, Seq d) -> Seq (a, b, c, d)-stup4 (a, b, c, d)- = Seq $ Stuple (NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d)--stup5 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e)- => (Seq a, Seq b, Seq c, Seq d, Seq e) -> Seq (a, b, c, d, e)-stup5 (a, b, c, d, e)- = Seq $ Stuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e--stup6 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f)- => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f) -> Seq (a, b, c, d, e, f)-stup6 (a, b, c, d, e, f)- = Seq $ Stuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c- `SnocAtup` d `SnocAtup` e `SnocAtup` f--stup7 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g)- => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g)- -> Seq (a, b, c, d, e, f, g)-stup7 (a, b, c, d, e, f, g)- = Seq $ Stuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c- `SnocAtup` d `SnocAtup` e `SnocAtup` f `SnocAtup` g--stup8 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h)- => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g, Seq h)- -> Seq (a, b, c, d, e, f, g, h)-stup8 (a, b, c, d, e, f, g, h)- = Seq $ Stuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d- `SnocAtup` e `SnocAtup` f `SnocAtup` g `SnocAtup` h--stup9 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i)- => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g, Seq h, Seq i)- -> Seq (a, b, c, d, e, f, g, h, i)-stup9 (a, b, c, d, e, f, g, h, i)- = Seq $ Stuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d- `SnocAtup` e `SnocAtup` f `SnocAtup` g `SnocAtup` h `SnocAtup` i--stup10 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j)- => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g, Seq h, Seq i, Seq j)- -> Seq (a, b, c, d, e, f, g, h, i, j)-stup10 (a, b, c, d, e, f, g, h, i, j)- = Seq $ Stuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e- `SnocAtup` f `SnocAtup` g `SnocAtup` h `SnocAtup` i `SnocAtup` j--stup11 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k)- => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g, Seq h, Seq i, Seq j, Seq k)- -> Seq (a, b, c, d, e, f, g, h, i, j, k)-stup11 (a, b, c, d, e, f, g, h, i, j, k)- = Seq $ Stuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e- `SnocAtup` f `SnocAtup` g `SnocAtup` h `SnocAtup` i `SnocAtup` j `SnocAtup` k--stup12 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l)- => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g, Seq h, Seq i, Seq j, Seq k, Seq l)- -> Seq (a, b, c, d, e, f, g, h, i, j, k, l)-stup12 (a, b, c, d, e, f, g, h, i, j, k, l)- = Seq $ Stuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e `SnocAtup` f- `SnocAtup` g `SnocAtup` h `SnocAtup` i `SnocAtup` j `SnocAtup` k `SnocAtup` l--stup13 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m)- => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g, Seq h, Seq i, Seq j, Seq k, Seq l, Seq m)- -> Seq (a, b, c, d, e, f, g, h, i, j, k, l, m)-stup13 (a, b, c, d, e, f, g, h, i, j, k, l, m)- = Seq $ Stuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e `SnocAtup` f- `SnocAtup` g `SnocAtup` h `SnocAtup` i `SnocAtup` j `SnocAtup` k `SnocAtup` l `SnocAtup` m--stup14 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m, Arrays n)- => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g, Seq h, Seq i, Seq j, Seq k, Seq l, Seq m, Seq n)- -> Seq (a, b, c, d, e, f, g, h, i, j, k, l, m, n)-stup14 (a, b, c, d, e, f, g, h, i, j, k, l, m, n)- = Seq $ Stuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e `SnocAtup` f `SnocAtup` g- `SnocAtup` h `SnocAtup` i `SnocAtup` j `SnocAtup` k `SnocAtup` l `SnocAtup` m `SnocAtup` n--stup15 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m, Arrays n, Arrays o)- => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g, Seq h, Seq i, Seq j, Seq k, Seq l, Seq m, Seq n, Seq o)- -> Seq (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)-stup15 (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)- = Seq $ Stuple $- NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e `SnocAtup` f `SnocAtup` g- `SnocAtup` h `SnocAtup` i `SnocAtup` j `SnocAtup` k `SnocAtup` l `SnocAtup` m `SnocAtup` n `SnocAtup` o---}---- Smart constructor for literals------- | Scalar expression inlet: make a Haskell value available for processing in--- an Accelerate scalar expression.------ Note that this embeds the value directly into the expression. Depending on--- the backend used to execute the computation, this might not always be--- desirable. For example, a backend that does external code generation may--- embed this constant directly into the generated code, which means new code--- will need to be generated and compiled every time the value changes. In such--- cases, consider instead lifting scalar values into (singleton) arrays so that--- they can be passed as an input to the computation and thus the value can--- change without the need to generate fresh code.----constant :: Elt t => t -> Exp t-constant = Exp . Const---- Smart constructor and destructors for scalar tuples----tup2 :: (Elt a, Elt b) => (Exp a, Exp b) -> Exp (a, b)-tup2 (a, b) = Exp $ Tuple (NilTup `SnocTup` a `SnocTup` b)--tup3 :: (Elt a, Elt b, Elt c) => (Exp a, Exp b, Exp c) -> Exp (a, b, c)-tup3 (a, b, c) = Exp $ Tuple (NilTup `SnocTup` a `SnocTup` b `SnocTup` c)--tup4 :: (Elt a, Elt b, Elt c, Elt d)- => (Exp a, Exp b, Exp c, Exp d) -> Exp (a, b, c, d)-tup4 (a, b, c, d)- = Exp $ Tuple (NilTup `SnocTup` a `SnocTup` b `SnocTup` c `SnocTup` d)--tup5 :: (Elt a, Elt b, Elt c, Elt d, Elt e)- => (Exp a, Exp b, Exp c, Exp d, Exp e) -> Exp (a, b, c, d, e)-tup5 (a, b, c, d, e)- = Exp $ Tuple $- NilTup `SnocTup` a `SnocTup` b `SnocTup` c `SnocTup` d `SnocTup` e--tup6 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f)- => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f) -> Exp (a, b, c, d, e, f)-tup6 (a, b, c, d, e, f)- = Exp $ Tuple $- NilTup `SnocTup` a `SnocTup` b `SnocTup` c `SnocTup` d `SnocTup` e `SnocTup` f--tup7 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g)- => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g)- -> Exp (a, b, c, d, e, f, g)-tup7 (a, b, c, d, e, f, g)- = Exp $ Tuple $- NilTup `SnocTup` a `SnocTup` b `SnocTup` c- `SnocTup` d `SnocTup` e `SnocTup` f `SnocTup` g--tup8 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h)- => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h)- -> Exp (a, b, c, d, e, f, g, h)-tup8 (a, b, c, d, e, f, g, h)- = Exp $ Tuple $- NilTup `SnocTup` a `SnocTup` b `SnocTup` c `SnocTup` d- `SnocTup` e `SnocTup` f `SnocTup` g `SnocTup` h--tup9 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i)- => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i)- -> Exp (a, b, c, d, e, f, g, h, i)-tup9 (a, b, c, d, e, f, g, h, i)- = Exp $ Tuple $- NilTup `SnocTup` a `SnocTup` b `SnocTup` c `SnocTup` d- `SnocTup` e `SnocTup` f `SnocTup` g `SnocTup` h `SnocTup` i--tup10 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j)- => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j)- -> Exp (a, b, c, d, e, f, g, h, i, j)-tup10 (a, b, c, d, e, f, g, h, i, j)- = Exp $ Tuple $- NilTup `SnocTup` a `SnocTup` b `SnocTup` c `SnocTup` d `SnocTup` e- `SnocTup` f `SnocTup` g `SnocTup` h `SnocTup` i `SnocTup` j--tup11 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k)- => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k)- -> Exp (a, b, c, d, e, f, g, h, i, j, k)-tup11 (a, b, c, d, e, f, g, h, i, j, k)- = Exp $ Tuple $- NilTup `SnocTup` a `SnocTup` b `SnocTup` c `SnocTup` d `SnocTup` e- `SnocTup` f `SnocTup` g `SnocTup` h `SnocTup` i `SnocTup` j `SnocTup` k--tup12 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l)- => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k, Exp l)- -> Exp (a, b, c, d, e, f, g, h, i, j, k, l)-tup12 (a, b, c, d, e, f, g, h, i, j, k, l)- = Exp $ Tuple $- NilTup `SnocTup` a `SnocTup` b `SnocTup` c `SnocTup` d `SnocTup` e `SnocTup` f- `SnocTup` g `SnocTup` h `SnocTup` i `SnocTup` j `SnocTup` k `SnocTup` l--tup13 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l, Elt m)- => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k, Exp l, Exp m)- -> Exp (a, b, c, d, e, f, g, h, i, j, k, l, m)-tup13 (a, b, c, d, e, f, g, h, i, j, k, l, m)- = Exp $ Tuple $- NilTup `SnocTup` a `SnocTup` b `SnocTup` c `SnocTup` d `SnocTup` e `SnocTup` f- `SnocTup` g `SnocTup` h `SnocTup` i `SnocTup` j `SnocTup` k `SnocTup` l `SnocTup` m--tup14 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l, Elt m, Elt n)- => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k, Exp l, Exp m, Exp n)- -> Exp (a, b, c, d, e, f, g, h, i, j, k, l, m, n)-tup14 (a, b, c, d, e, f, g, h, i, j, k, l, m, n)- = Exp $ Tuple $- NilTup `SnocTup` a `SnocTup` b `SnocTup` c `SnocTup` d `SnocTup` e `SnocTup` f `SnocTup` g- `SnocTup` h `SnocTup` i `SnocTup` j `SnocTup` k `SnocTup` l `SnocTup` m `SnocTup` n--tup15 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l, Elt m, Elt n, Elt o)- => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k, Exp l, Exp m, Exp n, Exp o)- -> Exp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)-tup15 (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)- = Exp $ Tuple $- NilTup `SnocTup` a `SnocTup` b `SnocTup` c `SnocTup` d `SnocTup` e `SnocTup` f `SnocTup` g- `SnocTup` h `SnocTup` i `SnocTup` j `SnocTup` k `SnocTup` l `SnocTup` m `SnocTup` n `SnocTup` o--untup2 :: (Elt a, Elt b) => Exp (a, b) -> (Exp a, Exp b)-untup2 e =- ( Exp $ SuccTupIdx ZeroTupIdx `Prj` e- , Exp $ ZeroTupIdx `Prj` e )--untup3 :: (Elt a, Elt b, Elt c) => Exp (a, b, c) -> (Exp a, Exp b, Exp c)-untup3 e =- ( Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` e- , Exp $ SuccTupIdx ZeroTupIdx `Prj` e- , Exp $ ZeroTupIdx `Prj` e)--untup4 :: (Elt a, Elt b, Elt c, Elt d)- => Exp (a, b, c, d) -> (Exp a, Exp b, Exp c, Exp d)-untup4 e =- ( Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` e- , Exp $ SuccTupIdx ZeroTupIdx `Prj` e- , Exp $ ZeroTupIdx `Prj` e)--untup5 :: (Elt a, Elt b, Elt c, Elt d, Elt e)- => Exp (a, b, c, d, e) -> (Exp a, Exp b, Exp c, Exp d, Exp e)-untup5 e =- ( Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` e- , Exp $ SuccTupIdx ZeroTupIdx `Prj` e- , Exp $ ZeroTupIdx `Prj` e)--untup6 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f)- => Exp (a, b, c, d, e, f) -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f)-untup6 e =- ( Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` e- , Exp $ SuccTupIdx ZeroTupIdx `Prj` e- , Exp $ ZeroTupIdx `Prj` e)--untup7 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g)- => Exp (a, b, c, d, e, f, g) -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g)-untup7 e =- ( Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` e- , Exp $ SuccTupIdx ZeroTupIdx `Prj` e- , Exp $ ZeroTupIdx `Prj` e)--untup8 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h)- => Exp (a, b, c, d, e, f, g, h) -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h)-untup8 e =- ( Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` e- , Exp $ SuccTupIdx ZeroTupIdx `Prj` e- , Exp $ ZeroTupIdx `Prj` e)--untup9 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i)- => Exp (a, b, c, d, e, f, g, h, i) -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i)-untup9 e =- ( Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` e- , Exp $ SuccTupIdx ZeroTupIdx `Prj` e- , Exp $ ZeroTupIdx `Prj` e)--untup10 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j)- => Exp (a, b, c, d, e, f, g, h, i, j) -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j)-untup10 e =- ( Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` e- , Exp $ SuccTupIdx ZeroTupIdx `Prj` e- , Exp $ ZeroTupIdx `Prj` e)--untup11 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k)- => Exp (a, b, c, d, e, f, g, h, i, j, k) -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k)-untup11 e =- ( Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` e- , Exp $ SuccTupIdx ZeroTupIdx `Prj` e- , Exp $ ZeroTupIdx `Prj` e)--untup12 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l)- => Exp (a, b, c, d, e, f, g, h, i, j, k, l) -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k, Exp l)-untup12 e =- ( Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` e- , Exp $ SuccTupIdx ZeroTupIdx `Prj` e- , Exp $ ZeroTupIdx `Prj` e)--untup13 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l, Elt m)- => Exp (a, b, c, d, e, f, g, h, i, j, k, l, m) -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k, Exp l, Exp m)-untup13 e =- ( Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` e- , Exp $ SuccTupIdx ZeroTupIdx `Prj` e- , Exp $ ZeroTupIdx `Prj` e)--untup14 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l, Elt m, Elt n)- => Exp (a, b, c, d, e, f, g, h, i, j, k, l, m, n) -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k, Exp l, Exp m, Exp n)-untup14 e =- ( Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` e- , Exp $ SuccTupIdx ZeroTupIdx `Prj` e- , Exp $ ZeroTupIdx `Prj` e)--untup15 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l, Elt m, Elt n, Elt o)- => Exp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k, Exp l, Exp m, Exp n, Exp o)-untup15 e =- ( Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx))) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx (SuccTupIdx ZeroTupIdx)) `Prj` e- , Exp $ SuccTupIdx (SuccTupIdx ZeroTupIdx) `Prj` e- , Exp $ SuccTupIdx ZeroTupIdx `Prj` e- , Exp $ ZeroTupIdx `Prj` e)---- Smart constructor for constants-----mkMinBound :: (Elt t, IsBounded t) => Exp t-mkMinBound = Exp $ PrimConst (PrimMinBound boundedType)--mkMaxBound :: (Elt t, IsBounded t) => Exp t-mkMaxBound = Exp $ PrimConst (PrimMaxBound boundedType)--mkPi :: (Elt r, IsFloating r) => Exp r-mkPi = Exp $ PrimConst (PrimPi floatingType)----- Smart constructors for primitive applications------- Operators from Floating--mkSin :: (Elt t, IsFloating t) => Exp t -> Exp t-mkSin x = Exp $ PrimSin floatingType `PrimApp` x--mkCos :: (Elt t, IsFloating t) => Exp t -> Exp t-mkCos x = Exp $ PrimCos floatingType `PrimApp` x--mkTan :: (Elt t, IsFloating t) => Exp t -> Exp t-mkTan x = Exp $ PrimTan floatingType `PrimApp` x--mkAsin :: (Elt t, IsFloating t) => Exp t -> Exp t-mkAsin x = Exp $ PrimAsin floatingType `PrimApp` x--mkAcos :: (Elt t, IsFloating t) => Exp t -> Exp t-mkAcos x = Exp $ PrimAcos floatingType `PrimApp` x--mkAtan :: (Elt t, IsFloating t) => Exp t -> Exp t-mkAtan x = Exp $ PrimAtan floatingType `PrimApp` x--mkSinh :: (Elt t, IsFloating t) => Exp t -> Exp t-mkSinh x = Exp $ PrimSinh floatingType `PrimApp` x--mkCosh :: (Elt t, IsFloating t) => Exp t -> Exp t-mkCosh x = Exp $ PrimCosh floatingType `PrimApp` x--mkTanh :: (Elt t, IsFloating t) => Exp t -> Exp t-mkTanh x = Exp $ PrimTanh floatingType `PrimApp` x--mkAsinh :: (Elt t, IsFloating t) => Exp t -> Exp t-mkAsinh x = Exp $ PrimAsinh floatingType `PrimApp` x--mkAcosh :: (Elt t, IsFloating t) => Exp t -> Exp t-mkAcosh x = Exp $ PrimAcosh floatingType `PrimApp` x--mkAtanh :: (Elt t, IsFloating t) => Exp t -> Exp t-mkAtanh x = Exp $ PrimAtanh floatingType `PrimApp` x--mkExpFloating :: (Elt t, IsFloating t) => Exp t -> Exp t-mkExpFloating x = Exp $ PrimExpFloating floatingType `PrimApp` x--mkSqrt :: (Elt t, IsFloating t) => Exp t -> Exp t-mkSqrt x = Exp $ PrimSqrt floatingType `PrimApp` x--mkLog :: (Elt t, IsFloating t) => Exp t -> Exp t-mkLog x = Exp $ PrimLog floatingType `PrimApp` x--mkFPow :: (Elt t, IsFloating t) => Exp t -> Exp t -> Exp t-mkFPow x y = Exp $ PrimFPow floatingType `PrimApp` tup2 (x, y)--mkLogBase :: (Elt t, IsFloating t) => Exp t -> Exp t -> Exp t-mkLogBase x y = Exp $ PrimLogBase floatingType `PrimApp` tup2 (x, y)---- Operators from Num--mkAdd :: (Elt t, IsNum t) => Exp t -> Exp t -> Exp t-mkAdd x y = Exp $ PrimAdd numType `PrimApp` tup2 (x, y)--mkSub :: (Elt t, IsNum t) => Exp t -> Exp t -> Exp t-mkSub x y = Exp $ PrimSub numType `PrimApp` tup2 (x, y)--mkMul :: (Elt t, IsNum t) => Exp t -> Exp t -> Exp t-mkMul x y = Exp $ PrimMul numType `PrimApp` tup2 (x, y)--mkNeg :: (Elt t, IsNum t) => Exp t -> Exp t-mkNeg x = Exp $ PrimNeg numType `PrimApp` x--mkAbs :: (Elt t, IsNum t) => Exp t -> Exp t-mkAbs x = Exp $ PrimAbs numType `PrimApp` x--mkSig :: (Elt t, IsNum t) => Exp t -> Exp t-mkSig x = Exp $ PrimSig numType `PrimApp` x---- Operators from Integral--mkQuot :: (Elt t, IsIntegral t) => Exp t -> Exp t -> Exp t-mkQuot x y = Exp $ PrimQuot integralType `PrimApp` tup2 (x, y)--mkRem :: (Elt t, IsIntegral t) => Exp t -> Exp t -> Exp t-mkRem x y = Exp $ PrimRem integralType `PrimApp` tup2 (x, y)--mkQuotRem :: (Elt t, IsIntegral t) => Exp t -> Exp t -> (Exp t, Exp t)-mkQuotRem x y = untup2 $ Exp $ PrimQuotRem integralType `PrimApp` tup2 (x ,y)--mkIDiv :: (Elt t, IsIntegral t) => Exp t -> Exp t -> Exp t-mkIDiv x y = Exp $ PrimIDiv integralType `PrimApp` tup2 (x, y)--mkMod :: (Elt t, IsIntegral t) => Exp t -> Exp t -> Exp t-mkMod x y = Exp $ PrimMod integralType `PrimApp` tup2 (x, y)--mkDivMod :: (Elt t, IsIntegral t) => Exp t -> Exp t -> (Exp t, Exp t)-mkDivMod x y = untup2 $ Exp $ PrimDivMod integralType `PrimApp` tup2 (x ,y)----- Operators from Bits and FiniteBits--mkBAnd :: (Elt t, IsIntegral t) => Exp t -> Exp t -> Exp t-mkBAnd x y = Exp $ PrimBAnd integralType `PrimApp` tup2 (x, y)--mkBOr :: (Elt t, IsIntegral t) => Exp t -> Exp t -> Exp t-mkBOr x y = Exp $ PrimBOr integralType `PrimApp` tup2 (x, y)--mkBXor :: (Elt t, IsIntegral t) => Exp t -> Exp t -> Exp t-mkBXor x y = Exp $ PrimBXor integralType `PrimApp` tup2 (x, y)--mkBNot :: (Elt t, IsIntegral t) => Exp t -> Exp t-mkBNot x = Exp $ PrimBNot integralType `PrimApp` x--mkBShiftL :: (Elt t, IsIntegral t) => Exp t -> Exp Int -> Exp t-mkBShiftL x i = Exp $ PrimBShiftL integralType `PrimApp` tup2 (x, i)--mkBShiftR :: (Elt t, IsIntegral t) => Exp t -> Exp Int -> Exp t-mkBShiftR x i = Exp $ PrimBShiftR integralType `PrimApp` tup2 (x, i)--mkBRotateL :: (Elt t, IsIntegral t) => Exp t -> Exp Int -> Exp t-mkBRotateL x i = Exp $ PrimBRotateL integralType `PrimApp` tup2 (x, i)--mkBRotateR :: (Elt t, IsIntegral t) => Exp t -> Exp Int -> Exp t-mkBRotateR x i = Exp $ PrimBRotateR integralType `PrimApp` tup2 (x, i)--mkPopCount :: (Elt t, IsIntegral t) => Exp t -> Exp Int-mkPopCount x = Exp $ PrimPopCount integralType `PrimApp` x--mkCountLeadingZeros :: (Elt t, IsIntegral t) => Exp t -> Exp Int-mkCountLeadingZeros x = Exp $ PrimCountLeadingZeros integralType `PrimApp` x--mkCountTrailingZeros :: (Elt t, IsIntegral t) => Exp t -> Exp Int-mkCountTrailingZeros x = Exp $ PrimCountTrailingZeros integralType `PrimApp` x----- Operators from Fractional--mkFDiv :: (Elt t, IsFloating t) => Exp t -> Exp t -> Exp t-mkFDiv x y = Exp $ PrimFDiv floatingType `PrimApp` tup2 (x, y)--mkRecip :: (Elt t, IsFloating t) => Exp t -> Exp t-mkRecip x = Exp $ PrimRecip floatingType `PrimApp` x---- Operators from RealFrac--mkTruncate :: (Elt a, Elt b, IsFloating a, IsIntegral b) => Exp a -> Exp b-mkTruncate x = Exp $ PrimTruncate floatingType integralType `PrimApp` x--mkRound :: (Elt a, Elt b, IsFloating a, IsIntegral b) => Exp a -> Exp b-mkRound x = Exp $ PrimRound floatingType integralType `PrimApp` x--mkFloor :: (Elt a, Elt b, IsFloating a, IsIntegral b) => Exp a -> Exp b-mkFloor x = Exp $ PrimFloor floatingType integralType `PrimApp` x--mkCeiling :: (Elt a, Elt b, IsFloating a, IsIntegral b) => Exp a -> Exp b-mkCeiling x = Exp $ PrimCeiling floatingType integralType `PrimApp` x---- Operators from RealFloat--mkAtan2 :: (Elt t, IsFloating t) => Exp t -> Exp t -> Exp t-mkAtan2 x y = Exp $ PrimAtan2 floatingType `PrimApp` tup2 (x, y)--mkIsNaN :: (Elt t, IsFloating t) => Exp t -> Exp Bool-mkIsNaN x = Exp $ PrimIsNaN floatingType `PrimApp` x+ Acc(..), PreAcc(..), Exp(..), PreExp(..), Boundary(..), PreBoundary(..), Stencil(..), Level,++ -- * Smart constructors for literals+ constant,++ -- * Smart constructors and destructors for tuples+ tup2, tup3, tup4, tup5, tup6, tup7, tup8, tup9, tup10, tup11, tup12, tup13, tup14, tup15,+ untup2, untup3, untup4, untup5, untup6, untup7, untup8, untup9, untup10, untup11, untup12, untup13, untup14, untup15,++ atup2, atup3, atup4, atup5, atup6, atup7, atup8, atup9, atup10, atup11, atup12, atup13, atup14, atup15,+ unatup2, unatup3, unatup4, unatup5, unatup6, unatup7, unatup8, unatup9, unatup10, unatup11, unatup12, unatup13, unatup14, unatup15,++ -- * Smart constructors for constants+ mkMinBound, mkMaxBound, mkPi,+ mkSin, mkCos, mkTan,+ mkAsin, mkAcos, mkAtan,+ mkSinh, mkCosh, mkTanh,+ mkAsinh, mkAcosh, mkAtanh,+ mkExpFloating, mkSqrt, mkLog,+ mkFPow, mkLogBase,+ mkTruncate, mkRound, mkFloor, mkCeiling,+ mkAtan2,++ -- * Smart constructors for primitive functions+ mkAdd, mkSub, mkMul, mkNeg, mkAbs, mkSig, mkQuot, mkRem, mkQuotRem, mkIDiv, mkMod, mkDivMod,+ mkBAnd, mkBOr, mkBXor, mkBNot, mkBShiftL, mkBShiftR, mkBRotateL, mkBRotateR, mkPopCount, mkCountLeadingZeros, mkCountTrailingZeros,+ mkFDiv, mkRecip, mkLt, mkGt, mkLtEq, mkGtEq, mkEq, mkNEq, mkMax, mkMin,+ mkLAnd, mkLOr, mkLNot, mkIsNaN, mkIsInfinite,++ -- * Smart constructors for type coercion functions+ mkOrd, mkChr, mkBoolToInt, mkFromIntegral, mkToFloating, mkBitcast, mkUnsafeCoerce,++ -- * Auxiliary functions+ ($$), ($$$), ($$$$), ($$$$$),++ -- Debugging+ showPreAccOp, showPreExpOp,++) where++-- standard library+import Prelude hiding ( exp )+import Data.List+import Data.Typeable++-- friends+import Data.Array.Accelerate.Type+import Data.Array.Accelerate.Array.Sugar+import Data.Array.Accelerate.Product+import Data.Array.Accelerate.AST hiding ( PreOpenAcc(..), OpenAcc(..), Acc+ , PreOpenExp(..), OpenExp, PreExp, Exp+ , Stencil(..), PreBoundary(..), Boundary+ , showPreAccOp, showPreExpOp )+import qualified Data.Array.Accelerate.AST as AST++-- Array computations+-- ------------------++-- | Accelerate is an /embedded language/ that distinguishes between vanilla+-- arrays (e.g. in Haskell memory on the CPU) and embedded arrays (e.g. in+-- device memory on a GPU), as well as the computations on both of these. Since+-- Accelerate is an embedded language, programs written in Accelerate are not+-- compiled by the Haskell compiler (GHC). Rather, each Accelerate backend is+-- a /runtime compiler/ which generates and executes parallel SIMD code of the+-- target language at application /runtime/.+--+-- The type constructor 'Acc' represents embedded collective array operations.+-- A term of type @Acc a@ is an Accelerate program which, once executed, will+-- produce a value of type 'a' (an 'Array' or a tuple of 'Arrays'). Collective+-- operations of type @Acc a@ comprise many /scalar expressions/, wrapped in+-- type constructor 'Exp', which will be executed in parallel. Although+-- collective operations comprise many scalar operations executed in parallel,+-- scalar operations /cannot/ initiate new collective operations: this+-- stratification between scalar operations in 'Exp' and array operations in+-- 'Acc' helps statically exclude /nested data parallelism/, which is difficult+-- to execute efficiently on constrained hardware such as GPUs.+--+-- For example, to compute a vector dot product we could write:+--+-- > dotp :: Num a => Vector a -> Vector a -> Acc (Scalar a)+-- > dotp xs ys =+-- > let+-- > xs' = use xs+-- > ys' = use ys+-- > in+-- > fold (+) 0 ( zipWith (*) xs' ys' )+--+-- The function @dotp@ consumes two one-dimensional arrays ('Vector's) of+-- values, and produces a single ('Scalar') result as output. As the return type+-- is wrapped in the type 'Acc', we see that it is an embedded Accelerate+-- computation - it will be evaluated in the /object/ language of dynamically+-- generated parallel code, rather than the /meta/ language of vanilla Haskell.+--+-- As the arguments to @dotp@ are plain Haskell arrays, to make these available+-- to Accelerate computations they must be embedded with the+-- 'Data.Array.Accelerate.Language.use' function.+--+-- An Accelerate backend is used to evaluate the embedded computation and return+-- the result back to vanilla Haskell. Calling the 'run' function of a backend+-- will generate code for the target architecture, compile, and execute it. For+-- example, the following backends are available:+--+-- * <http://hackage.haskell.org/package/accelerate-llvm-native accelerate-llvm-native>: for execution on multicore CPUs+-- * <http://hackage.haskell.org/package/accelerate-llvm-ptx accelerate-llvm-ptx>: for execution on NVIDIA CUDA-capable GPUs+--+-- See also 'Exp', which encapsulates embedded /scalar/ computations.+--+-- [/Fusion:/]+--+-- Array computations of type 'Acc' will be subject to /array fusion/;+-- Accelerate will combine individual 'Acc' computations into a single+-- computation, which reduces the number of traversals over the input data and+-- thus improves performance. As such, it is often useful to have some intuition+-- on when fusion should occur.+--+-- The main idea is to first partition array operations into two categories:+--+-- 1. Element-wise operations, such as 'Data.Array.Accelerate.map',+-- 'Data.Array.Accelerate.generate', and+-- 'Data.Array.Accelerate.backpermute'. Each element of these operations+-- can be computed independently of all others.+--+-- 2. Collective operations such as 'Data.Array.Accelerate.fold',+-- 'Data.Array.Accelerate.scanl', and 'Data.Array.Accelerate.stencil'. To+-- compute each output element of these operations requires reading+-- multiple elements from the input array(s).+--+-- Element-wise operations fuse together whenever the consumer operation uses+-- a single element of the input array. Element-wise operations can both fuse+-- their inputs into themselves, as well be fused into later operations. Both+-- these examples should fuse into a single loop:+--+-- > map -> reverse -> reshape -> map -> map+--+-- > map -> backpermute ->+-- > zipWith -> map+-- > generate ->+--+-- If the consumer operation uses more than one element of the input array+-- (typically, via 'Data.Array.Accelerate.generate' indexing an array multiple+-- times), then the input array will be completely evaluated first; no fusion+-- occurs in this case, because fusing the first operation into the second+-- implies duplicating work.+--+-- On the other hand, collective operations can fuse their input arrays into+-- themselves, but on output always evaluate to an array; collective operations+-- will not be fused into a later step. For example:+--+-- > use ->+-- > zipWith -> fold |-> map+-- > generate ->+--+-- Here the element-wise sequence ('Data.Array.Accelerate.use'+-- + 'Data.Array.Accelerate.generate' + 'Data.Array.Accelerate.zipWith') will+-- fuse into a single operation, which then fuses into the collective+-- 'Data.Array.Accelerate.fold' operation. At this point in the program the+-- 'Data.Array.Accelerate.fold' must now be evaluated. In the final step the+-- 'Data.Array.Accelerate.map' reads in the array produced by+-- 'Data.Array.Accelerate.fold'. As there is no fusion between the+-- 'Data.Array.Accelerate.fold' and 'Data.Array.Accelerate.map' steps, this+-- program consists of two "loops"; one for the 'Data.Array.Accelerate.use'+-- + 'Data.Array.Accelerate.generate' + 'Data.Array.Accelerate.zipWith'+-- + 'Data.Array.Accelerate.fold' step, and one for the final+-- 'Data.Array.Accelerate.map' step.+--+-- You can see how many operations will be executed in the fused program by+-- 'Show'-ing the 'Acc' program, or by using the debugging option @-ddump-dot@+-- to save the program as a graphviz DOT file.+--+-- As a special note, the operations 'Data.Array.Accelerate.unzip' and+-- 'Data.Array.Accelerate.reshape', when applied to a real array, are executed+-- in constant time, so in this situation these operations will not be fused.+--+-- [/Tips:/]+--+-- * Since 'Acc' represents embedded computations that will only be executed+-- when evaluated by a backend, we can programatically generate these+-- computations using the meta language Haskell; for example, unrolling loops+-- or embedding input values into the generated code.+--+-- * It is usually best to keep all intermediate computations in 'Acc', and+-- only 'run' the computation at the very end to produce the final result.+-- This enables optimisations between intermediate results (e.g. array+-- fusion) and, if the target architecture has a separate memory space as is+-- the case of GPUs, to prevent excessive data transfers.+--+newtype Acc a = Acc (PreAcc Acc Exp a)+deriving instance Typeable Acc+++-- The level of lambda-bound variables. The root has level 0; then it increases with each bound+-- variable — i.e., it is the same as the size of the environment at the defining occurrence.+--+type Level = Int++-- | Array-valued collective computations without a recursive knot+--+data PreAcc acc exp as where+ -- Needed for conversion to de Bruijn form+ Atag :: Arrays as+ => Level -- environment size at defining occurrence+ -> PreAcc acc exp as++ Pipe :: (Arrays as, Arrays bs, Arrays cs)+ => (Acc as -> acc bs)+ -> (Acc bs -> acc cs)+ -> acc as+ -> PreAcc acc exp cs++ Aforeign :: (Arrays as, Arrays bs, Foreign asm)+ => asm (as -> bs)+ -> (Acc as -> Acc bs)+ -> acc as+ -> PreAcc acc exp bs++ Acond :: Arrays as+ => exp Bool+ -> acc as+ -> acc as+ -> PreAcc acc exp as++ Awhile :: Arrays arrs+ => (Acc arrs -> acc (Scalar Bool))+ -> (Acc arrs -> acc arrs)+ -> acc arrs+ -> PreAcc acc exp arrs++ Atuple :: (Arrays arrs, IsAtuple arrs)+ => Atuple acc (TupleRepr arrs)+ -> PreAcc acc exp arrs++ Aprj :: (Arrays arrs, IsAtuple arrs, Arrays a)+ => TupleIdx (TupleRepr arrs) a+ -> acc arrs+ -> PreAcc acc exp a++ Use :: Arrays arrs+ => arrs+ -> PreAcc acc exp arrs++ Unit :: Elt e+ => exp e+ -> PreAcc acc exp (Scalar e)++ Generate :: (Shape sh, Elt e)+ => exp sh+ -> (Exp sh -> exp e)+ -> PreAcc acc exp (Array sh e)++ Reshape :: (Shape sh, Shape sh', Elt e)+ => exp sh+ -> acc (Array sh' e)+ -> PreAcc acc exp (Array sh e)++ Replicate :: (Slice slix, Elt e)+ => exp slix+ -> acc (Array (SliceShape slix) e)+ -> PreAcc acc exp (Array (FullShape slix) e)++ Slice :: (Slice slix, Elt e)+ => acc (Array (FullShape slix) e)+ -> exp slix+ -> PreAcc acc exp (Array (SliceShape slix) e)++ Map :: (Shape sh, Elt e, Elt e')+ => (Exp e -> exp e')+ -> acc (Array sh e)+ -> PreAcc acc exp (Array sh e')++ ZipWith :: (Shape sh, Elt e1, Elt e2, Elt e3)+ => (Exp e1 -> Exp e2 -> exp e3)+ -> acc (Array sh e1)+ -> acc (Array sh e2)+ -> PreAcc acc exp (Array sh e3)++ Fold :: (Shape sh, Elt e)+ => (Exp e -> Exp e -> exp e)+ -> exp e+ -> acc (Array (sh:.Int) e)+ -> PreAcc acc exp (Array sh e)++ Fold1 :: (Shape sh, Elt e)+ => (Exp e -> Exp e -> exp e)+ -> acc (Array (sh:.Int) e)+ -> PreAcc acc exp (Array sh e)++ FoldSeg :: (Shape sh, Elt e, Elt i, IsIntegral i)+ => (Exp e -> Exp e -> exp e)+ -> exp e+ -> acc (Array (sh:.Int) e)+ -> acc (Segments i)+ -> PreAcc acc exp (Array (sh:.Int) e)++ Fold1Seg :: (Shape sh, Elt e, Elt i, IsIntegral i)+ => (Exp e -> Exp e -> exp e)+ -> acc (Array (sh:.Int) e)+ -> acc (Segments i)+ -> PreAcc acc exp (Array (sh:.Int) e)++ Scanl :: (Shape sh, Elt e)+ => (Exp e -> Exp e -> exp e)+ -> exp e+ -> acc (Array (sh :. Int) e)+ -> PreAcc acc exp (Array (sh :. Int) e)++ Scanl' :: (Shape sh, Elt e)+ => (Exp e -> Exp e -> exp e)+ -> exp e+ -> acc (Array (sh :. Int) e)+ -> PreAcc acc exp (Array (sh :. Int) e, Array sh e)++ Scanl1 :: (Shape sh, Elt e)+ => (Exp e -> Exp e -> exp e)+ -> acc (Array (sh :. Int) e)+ -> PreAcc acc exp (Array (sh :. Int) e)++ Scanr :: (Shape sh, Elt e)+ => (Exp e -> Exp e -> exp e)+ -> exp e+ -> acc (Array (sh :. Int) e)+ -> PreAcc acc exp (Array (sh :. Int) e)++ Scanr' :: (Shape sh, Elt e)+ => (Exp e -> Exp e -> exp e)+ -> exp e+ -> acc (Array (sh :. Int) e)+ -> PreAcc acc exp (Array (sh :. Int) e, Array sh e)++ Scanr1 :: (Shape sh, Elt e)+ => (Exp e -> Exp e -> exp e)+ -> acc (Array (sh :. Int) e)+ -> PreAcc acc exp (Array (sh :. Int) e)++ Permute :: (Shape sh, Shape sh', Elt e)+ => (Exp e -> Exp e -> exp e)+ -> acc (Array sh' e)+ -> (Exp sh -> exp sh')+ -> acc (Array sh e)+ -> PreAcc acc exp (Array sh' e)++ Backpermute :: (Shape sh, Shape sh', Elt e)+ => exp sh'+ -> (Exp sh' -> exp sh)+ -> acc (Array sh e)+ -> PreAcc acc exp (Array sh' e)++ Stencil :: (Shape sh, Elt a, Elt b, Stencil sh a stencil)+ => (stencil -> exp b)+ -> PreBoundary acc exp (Array sh a)+ -> acc (Array sh a)+ -> PreAcc acc exp (Array sh b)++ Stencil2 :: (Shape sh, Elt a, Elt b, Elt c, Stencil sh a stencil1, Stencil sh b stencil2)+ => (stencil1 -> stencil2 -> exp c)+ -> PreBoundary acc exp (Array sh a)+ -> acc (Array sh a)+ -> PreBoundary acc exp (Array sh b)+ -> acc (Array sh b)+ -> PreAcc acc exp (Array sh c)++ -- Collect :: Arrays arrs+ -- => seq arrs+ -- -> PreAcc acc seq exp arrs+++{--+data PreSeq acc seq exp arrs where+ -- Convert the given Haskell-list of arrays to a sequence.+ StreamIn :: Arrays a+ => [a]+ -> PreSeq acc seq exp [a]++ -- Convert the given array to a sequence.+ -- Example:+ -- slix = Z :. All :. Split :. All :. All :. Split+ -- ^ ^ ^ ^ ^+ -- | \ / / |+ -- | \___/______/_______ Iteration space.+ -- | / /+ -- Element________/______/+ -- shape.+ --+ ToSeq :: ( Elt e+ , Slice slix+ , Division slsix+ , DivisionSlice slsix ~ slix+ , Typeable (FullShape slix)+ , Typeable (SliceShape slix)+ )+ => slsix+ -> acc (Array (FullShape slix) e)+ -> PreSeq acc seq exp [Array (SliceShape slix) e]++ -- Apply the given the given function to all elements of the given sequence.+ MapSeq :: (Arrays a, Arrays b)+ => (Acc a -> acc b)+ -> seq [a]+ -> PreSeq acc seq exp [b]++ -- Apply a given binary function pairwise to all elements of the given sequences.+ -- The length of the result is the length of the shorter of the two argument+ -- arrays.+ ZipWithSeq :: (Arrays a, Arrays b, Arrays c)+ => (Acc a -> Acc b -> acc c)+ -> seq [a]+ -> seq [b]+ -> PreSeq acc seq exp [c]++ -- ScanSeq (+) a0 x. Scan a sequence x by combining each element+ -- using the given binary operation (+). (+) must be associative:+ --+ -- Forall a b c. (a + b) + c = a + (b + c),+ --+ -- and a0 must be the identity element for (+):+ --+ -- Forall a. a0 + a = a = a + a0.+ --+ ScanSeq :: Elt a+ => (Exp a -> Exp a -> exp a)+ -> exp a+ -> seq [Scalar a]+ -> PreSeq acc seq exp [Scalar a]++ -- FoldSeq (+) a0 x. Fold a sequence x by combining each element+ -- using the given binary operation (+). (+) must be associative:+ --+ -- Forall a b c. (a + b) + c = a + (b + c),+ --+ -- and a0 must be the identity element for (+):+ --+ -- Forall a. a0 + a = a = a + a0.+ --+ FoldSeq :: Elt a+ => (Exp a -> Exp a -> exp a)+ -> exp a+ -> seq [Scalar a]+ -> PreSeq acc seq exp (Scalar a)++ -- FoldSeqFlatten f a0 x. A specialized version of FoldSeqAct+ -- where reduction with the companion operator corresponds to+ -- flattening. f must be semi-associative, with vecotor append (++)+ -- as the companion operator:+ --+ -- Forall b s1 a2 sh2 a2.+ -- f (f b sh1 a1) sh2 a2 = f b (sh1 ++ sh2) (a1 ++ a2).+ --+ -- It is common to ignore the shape vectors, yielding the usual+ -- semi-associativity law:+ --+ -- f b a _ = b + a,+ --+ -- for some (+) satisfying:+ --+ -- Forall b a1 a2. (b + a1) + a2 = b + (a1 ++ a2).+ --+ FoldSeqFlatten :: (Arrays a, Shape sh, Elt e)+ => (Acc a -> Acc (Vector sh) -> Acc (Vector e) -> acc a)+ -> acc a+ -> seq [Array sh e]+ -> PreSeq acc seq exp a++ -- Tuple up the results of a sequence computation. Note that the Arrays+ -- constraint requires that the elements of the tuple are Arrays, not+ -- streams ([]).+ Stuple :: (Arrays arrs, IsAtuple arrs)+ => Atuple (seq) (TupleRepr arrs)+ -> PreSeq acc seq exp arrs++-- |Array-valued sequence computations+--+newtype Seq a = Seq (PreSeq Acc Seq Exp a)++deriving instance Typeable Seq+--}+++-- Embedded expressions of the surface language+-- --------------------------------------------++-- HOAS expressions mirror the constructors of 'AST.OpenExp', but with the 'Tag'+-- constructor instead of variables in the form of de Bruijn indices. Moreover,+-- HOAS expression use n-tuples and the type class 'Elt' to constrain element+-- types, whereas 'AST.OpenExp' uses nested pairs and the GADT 'TupleType'.+--++-- | The type 'Exp' represents embedded scalar expressions. The collective+-- operations of Accelerate 'Acc' consist of many scalar expressions executed in+-- data-parallel.+--+-- Note that scalar expressions can not initiate new collective operations:+-- doing so introduces /nested data parallelism/, which is difficult to execute+-- efficiently on constrained hardware such as GPUs, and is thus currently+-- unsupported.+--+newtype Exp t = Exp (PreExp Acc Exp t)++deriving instance Typeable Exp++-- | Scalar expressions to parametrise collective array operations, themselves parameterised over+-- the type of collective array operations.+--+data PreExp acc exp t where+ -- Needed for conversion to de Bruijn form+ Tag :: Elt t+ => Level -- environment size at defining occurrence+ -> PreExp acc exp t++ -- All the same constructors as 'AST.Exp'+ Const :: Elt t+ => t+ -> PreExp acc exp t++ Tuple :: (Elt t, IsTuple t)+ => Tuple exp (TupleRepr t)+ -> PreExp acc exp t++ Prj :: (Elt t, IsTuple t, Elt e)+ => TupleIdx (TupleRepr t) e+ -> exp t+ -> PreExp acc exp e++ IndexNil :: PreExp acc exp Z++ IndexCons :: (Slice sl, Elt a)+ => exp sl+ -> exp a+ -> PreExp acc exp (sl:.a)++ IndexHead :: (Slice sl, Elt a)+ => exp (sl:.a)+ -> PreExp acc exp a++ IndexTail :: (Slice sl, Elt a)+ => exp (sl:.a)+ -> PreExp acc exp sl++ IndexAny :: Shape sh+ => PreExp acc exp (Any sh)++ ToIndex :: Shape sh+ => exp sh+ -> exp sh+ -> PreExp acc exp Int++ FromIndex :: Shape sh+ => exp sh+ -> exp Int+ -> PreExp acc exp sh++ Cond :: Elt t+ => exp Bool+ -> exp t+ -> exp t+ -> PreExp acc exp t++ While :: Elt t+ => (Exp t -> exp Bool)+ -> (Exp t -> exp t)+ -> exp t+ -> PreExp acc exp t++ PrimConst :: Elt t+ => PrimConst t+ -> PreExp acc exp t++ PrimApp :: (Elt a, Elt r)+ => PrimFun (a -> r)+ -> exp a+ -> PreExp acc exp r++ Index :: (Shape sh, Elt t)+ => acc (Array sh t)+ -> exp sh+ -> PreExp acc exp t++ LinearIndex :: (Shape sh, Elt t)+ => acc (Array sh t)+ -> exp Int+ -> PreExp acc exp t++ Shape :: (Shape sh, Elt e)+ => acc (Array sh e)+ -> PreExp acc exp sh++ ShapeSize :: Shape sh+ => exp sh+ -> PreExp acc exp Int++ Intersect :: Shape sh+ => exp sh+ -> exp sh+ -> PreExp acc exp sh++ Union :: Shape sh+ => exp sh+ -> exp sh+ -> PreExp acc exp sh++ Foreign :: (Elt x, Elt y, Foreign asm)+ => asm (x -> y)+ -> (Exp x -> Exp y) -- RCE: Using Exp instead of exp to aid in sharing recovery.+ -> exp x+ -> PreExp acc exp y+++-- Smart constructors and destructors for array tuples+-- ---------------------------------------------------++atup2 :: (Arrays a, Arrays b)+ => (Acc a, Acc b)+ -> Acc (a, b)+atup2 (a, b)+ = Acc+ $ Atuple+ $ NilAtup `SnocAtup` a+ `SnocAtup` b++atup3 :: (Arrays a, Arrays b, Arrays c)+ => (Acc a, Acc b, Acc c)+ -> Acc (a, b, c)+atup3 (a, b, c)+ = Acc $ Atuple+ $ NilAtup `SnocAtup` a+ `SnocAtup` b+ `SnocAtup` c++atup4 :: (Arrays a, Arrays b, Arrays c, Arrays d)+ => (Acc a, Acc b, Acc c, Acc d)+ -> Acc (a, b, c, d)+atup4 (a, b, c, d)+ = Acc+ $ Atuple+ $ NilAtup `SnocAtup` a+ `SnocAtup` b+ `SnocAtup` c+ `SnocAtup` d++atup5 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e)+ => (Acc a, Acc b, Acc c, Acc d, Acc e)+ -> Acc (a, b, c, d, e)+atup5 (a, b, c, d, e)+ = Acc+ $ Atuple+ $ NilAtup `SnocAtup` a+ `SnocAtup` b+ `SnocAtup` c+ `SnocAtup` d+ `SnocAtup` e++atup6 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f)+ => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f)+ -> Acc (a, b, c, d, e, f)+atup6 (a, b, c, d, e, f)+ = Acc+ $ Atuple+ $ NilAtup `SnocAtup` a+ `SnocAtup` b+ `SnocAtup` c+ `SnocAtup` d+ `SnocAtup` e+ `SnocAtup` f++atup7 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g)+ => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g)+ -> Acc (a, b, c, d, e, f, g)+atup7 (a, b, c, d, e, f, g)+ = Acc+ $ Atuple+ $ NilAtup `SnocAtup` a+ `SnocAtup` b+ `SnocAtup` c+ `SnocAtup` d+ `SnocAtup` e+ `SnocAtup` f+ `SnocAtup` g++atup8 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h)+ => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h)+ -> Acc (a, b, c, d, e, f, g, h)+atup8 (a, b, c, d, e, f, g, h)+ = Acc+ $ Atuple+ $ NilAtup `SnocAtup` a+ `SnocAtup` b+ `SnocAtup` c+ `SnocAtup` d+ `SnocAtup` e+ `SnocAtup` f+ `SnocAtup` g+ `SnocAtup` h++atup9 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i)+ => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i)+ -> Acc (a, b, c, d, e, f, g, h, i)+atup9 (a, b, c, d, e, f, g, h, i)+ = Acc+ $ Atuple+ $ NilAtup `SnocAtup` a+ `SnocAtup` b+ `SnocAtup` c+ `SnocAtup` d+ `SnocAtup` e+ `SnocAtup` f+ `SnocAtup` g+ `SnocAtup` h+ `SnocAtup` i++atup10 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j)+ => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j)+ -> Acc (a, b, c, d, e, f, g, h, i, j)+atup10 (a, b, c, d, e, f, g, h, i, j)+ = Acc+ $ Atuple+ $ NilAtup `SnocAtup` a+ `SnocAtup` b+ `SnocAtup` c+ `SnocAtup` d+ `SnocAtup` e+ `SnocAtup` f+ `SnocAtup` g+ `SnocAtup` h+ `SnocAtup` i+ `SnocAtup` j++atup11 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k)+ => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k)+ -> Acc (a, b, c, d, e, f, g, h, i, j, k)+atup11 (a, b, c, d, e, f, g, h, i, j, k)+ = Acc+ $ Atuple+ $ NilAtup `SnocAtup` a+ `SnocAtup` b+ `SnocAtup` c+ `SnocAtup` d+ `SnocAtup` e+ `SnocAtup` f+ `SnocAtup` g+ `SnocAtup` h+ `SnocAtup` i+ `SnocAtup` j+ `SnocAtup` k++atup12 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l)+ => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k, Acc l)+ -> Acc (a, b, c, d, e, f, g, h, i, j, k, l)+atup12 (a, b, c, d, e, f, g, h, i, j, k, l)+ = Acc+ $ Atuple+ $ NilAtup `SnocAtup` a+ `SnocAtup` b+ `SnocAtup` c+ `SnocAtup` d+ `SnocAtup` e+ `SnocAtup` f+ `SnocAtup` g+ `SnocAtup` h+ `SnocAtup` i+ `SnocAtup` j+ `SnocAtup` k+ `SnocAtup` l++atup13 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m)+ => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k, Acc l, Acc m)+ -> Acc (a, b, c, d, e, f, g, h, i, j, k, l, m)+atup13 (a, b, c, d, e, f, g, h, i, j, k, l, m)+ = Acc+ $ Atuple+ $ NilAtup `SnocAtup` a+ `SnocAtup` b+ `SnocAtup` c+ `SnocAtup` d+ `SnocAtup` e+ `SnocAtup` f+ `SnocAtup` g+ `SnocAtup` h+ `SnocAtup` i+ `SnocAtup` j+ `SnocAtup` k+ `SnocAtup` l+ `SnocAtup` m++atup14 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m, Arrays n)+ => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k, Acc l, Acc m, Acc n)+ -> Acc (a, b, c, d, e, f, g, h, i, j, k, l, m, n)+atup14 (a, b, c, d, e, f, g, h, i, j, k, l, m, n)+ = Acc+ $ Atuple+ $ NilAtup `SnocAtup` a+ `SnocAtup` b+ `SnocAtup` c+ `SnocAtup` d+ `SnocAtup` e+ `SnocAtup` f+ `SnocAtup` g+ `SnocAtup` h+ `SnocAtup` i+ `SnocAtup` j+ `SnocAtup` k+ `SnocAtup` l+ `SnocAtup` m+ `SnocAtup` n++atup15 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m, Arrays n, Arrays o)+ => (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k, Acc l, Acc m, Acc n, Acc o)+ -> Acc (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)+atup15 (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)+ = Acc+ $ Atuple+ $ NilAtup `SnocAtup` a+ `SnocAtup` b+ `SnocAtup` c+ `SnocAtup` d+ `SnocAtup` e+ `SnocAtup` f+ `SnocAtup` g+ `SnocAtup` h+ `SnocAtup` i+ `SnocAtup` j+ `SnocAtup` k+ `SnocAtup` l+ `SnocAtup` m+ `SnocAtup` n+ `SnocAtup` o++unatup2 :: (Arrays a, Arrays b)+ => Acc (a, b)+ -> (Acc a, Acc b)+unatup2 e =+ ( Acc $ tix1 `Aprj` e+ , Acc $ tix0 `Aprj` e )++unatup3 :: (Arrays a, Arrays b, Arrays c)+ => Acc (a, b, c)+ -> (Acc a, Acc b, Acc c)+unatup3 e =+ ( Acc $ tix2 `Aprj` e+ , Acc $ tix1 `Aprj` e+ , Acc $ tix0 `Aprj` e )++unatup4+ :: (Arrays a, Arrays b, Arrays c, Arrays d)+ => Acc (a, b, c, d)+ -> (Acc a, Acc b, Acc c, Acc d)+unatup4 e =+ ( Acc $ tix3 `Aprj` e+ , Acc $ tix2 `Aprj` e+ , Acc $ tix1 `Aprj` e+ , Acc $ tix0 `Aprj` e )++unatup5+ :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e)+ => Acc (a, b, c, d, e)+ -> (Acc a, Acc b, Acc c, Acc d, Acc e)+unatup5 e =+ ( Acc $ tix4 `Aprj` e+ , Acc $ tix3 `Aprj` e+ , Acc $ tix2 `Aprj` e+ , Acc $ tix1 `Aprj` e+ , Acc $ tix0 `Aprj` e )++unatup6+ :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f)+ => Acc (a, b, c, d, e, f)+ -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f)+unatup6 e =+ ( Acc $ tix5 `Aprj` e+ , Acc $ tix4 `Aprj` e+ , Acc $ tix3 `Aprj` e+ , Acc $ tix2 `Aprj` e+ , Acc $ tix1 `Aprj` e+ , Acc $ tix0 `Aprj` e )++unatup7+ :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g)+ => Acc (a, b, c, d, e, f, g)+ -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g)+unatup7 e =+ ( Acc $ tix6 `Aprj` e+ , Acc $ tix5 `Aprj` e+ , Acc $ tix4 `Aprj` e+ , Acc $ tix3 `Aprj` e+ , Acc $ tix2 `Aprj` e+ , Acc $ tix1 `Aprj` e+ , Acc $ tix0 `Aprj` e )++unatup8+ :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h)+ => Acc (a, b, c, d, e, f, g, h)+ -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h)+unatup8 e =+ ( Acc $ tix7 `Aprj` e+ , Acc $ tix6 `Aprj` e+ , Acc $ tix5 `Aprj` e+ , Acc $ tix4 `Aprj` e+ , Acc $ tix3 `Aprj` e+ , Acc $ tix2 `Aprj` e+ , Acc $ tix1 `Aprj` e+ , Acc $ tix0 `Aprj` e )++unatup9+ :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i)+ => Acc (a, b, c, d, e, f, g, h, i)+ -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i)+unatup9 e =+ ( Acc $ tix8 `Aprj` e+ , Acc $ tix7 `Aprj` e+ , Acc $ tix6 `Aprj` e+ , Acc $ tix5 `Aprj` e+ , Acc $ tix4 `Aprj` e+ , Acc $ tix3 `Aprj` e+ , Acc $ tix2 `Aprj` e+ , Acc $ tix1 `Aprj` e+ , Acc $ tix0 `Aprj` e )++unatup10+ :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j)+ => Acc (a, b, c, d, e, f, g, h, i, j)+ -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j)+unatup10 e =+ ( Acc $ tix9 `Aprj` e+ , Acc $ tix8 `Aprj` e+ , Acc $ tix7 `Aprj` e+ , Acc $ tix6 `Aprj` e+ , Acc $ tix5 `Aprj` e+ , Acc $ tix4 `Aprj` e+ , Acc $ tix3 `Aprj` e+ , Acc $ tix2 `Aprj` e+ , Acc $ tix1 `Aprj` e+ , Acc $ tix0 `Aprj` e )++unatup11+ :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k)+ => Acc (a, b, c, d, e, f, g, h, i, j, k)+ -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k)+unatup11 e =+ ( Acc $ tix10 `Aprj` e+ , Acc $ tix9 `Aprj` e+ , Acc $ tix8 `Aprj` e+ , Acc $ tix7 `Aprj` e+ , Acc $ tix6 `Aprj` e+ , Acc $ tix5 `Aprj` e+ , Acc $ tix4 `Aprj` e+ , Acc $ tix3 `Aprj` e+ , Acc $ tix2 `Aprj` e+ , Acc $ tix1 `Aprj` e+ , Acc $ tix0 `Aprj` e )++unatup12+ :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l)+ => Acc (a, b, c, d, e, f, g, h, i, j, k, l)+ -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k, Acc l)+unatup12 e =+ ( Acc $ tix11 `Aprj` e+ , Acc $ tix10 `Aprj` e+ , Acc $ tix9 `Aprj` e+ , Acc $ tix8 `Aprj` e+ , Acc $ tix7 `Aprj` e+ , Acc $ tix6 `Aprj` e+ , Acc $ tix5 `Aprj` e+ , Acc $ tix4 `Aprj` e+ , Acc $ tix3 `Aprj` e+ , Acc $ tix2 `Aprj` e+ , Acc $ tix1 `Aprj` e+ , Acc $ tix0 `Aprj` e )++unatup13+ :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m)+ => Acc (a, b, c, d, e, f, g, h, i, j, k, l, m)+ -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k, Acc l, Acc m)+unatup13 e =+ ( Acc $ tix12 `Aprj` e+ , Acc $ tix11 `Aprj` e+ , Acc $ tix10 `Aprj` e+ , Acc $ tix9 `Aprj` e+ , Acc $ tix8 `Aprj` e+ , Acc $ tix7 `Aprj` e+ , Acc $ tix6 `Aprj` e+ , Acc $ tix5 `Aprj` e+ , Acc $ tix4 `Aprj` e+ , Acc $ tix3 `Aprj` e+ , Acc $ tix2 `Aprj` e+ , Acc $ tix1 `Aprj` e+ , Acc $ tix0 `Aprj` e )++unatup14+ :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m, Arrays n)+ => Acc (a, b, c, d, e, f, g, h, i, j, k, l, m, n)+ -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k, Acc l, Acc m, Acc n)+unatup14 e =+ ( Acc $ tix13 `Aprj` e+ , Acc $ tix12 `Aprj` e+ , Acc $ tix11 `Aprj` e+ , Acc $ tix10 `Aprj` e+ , Acc $ tix9 `Aprj` e+ , Acc $ tix8 `Aprj` e+ , Acc $ tix7 `Aprj` e+ , Acc $ tix6 `Aprj` e+ , Acc $ tix5 `Aprj` e+ , Acc $ tix4 `Aprj` e+ , Acc $ tix3 `Aprj` e+ , Acc $ tix2 `Aprj` e+ , Acc $ tix1 `Aprj` e+ , Acc $ tix0 `Aprj` e )++unatup15+ :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m, Arrays n, Arrays o)+ => Acc (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)+ -> (Acc a, Acc b, Acc c, Acc d, Acc e, Acc f, Acc g, Acc h, Acc i, Acc j, Acc k, Acc l, Acc m, Acc n, Acc o)+unatup15 e =+ ( Acc $ tix14 `Aprj` e+ , Acc $ tix13 `Aprj` e+ , Acc $ tix12 `Aprj` e+ , Acc $ tix11 `Aprj` e+ , Acc $ tix10 `Aprj` e+ , Acc $ tix9 `Aprj` e+ , Acc $ tix8 `Aprj` e+ , Acc $ tix7 `Aprj` e+ , Acc $ tix6 `Aprj` e+ , Acc $ tix5 `Aprj` e+ , Acc $ tix4 `Aprj` e+ , Acc $ tix3 `Aprj` e+ , Acc $ tix2 `Aprj` e+ , Acc $ tix1 `Aprj` e+ , Acc $ tix0 `Aprj` e )+++-- Smart constructors for stencils+-- -------------------------------++-- | Boundary condition specification for stencil operations+--+newtype Boundary t = Boundary (PreBoundary Acc Exp t)++data PreBoundary acc exp t where+ Clamp :: PreBoundary acc exp t+ Mirror :: PreBoundary acc exp t+ Wrap :: PreBoundary acc exp t++ Constant :: Elt e+ => e+ -> PreBoundary acc exp (Array sh e)++ Function :: (Shape sh, Elt e)+ => (Exp sh -> exp e)+ -> PreBoundary acc exp (Array sh e)+++-- Stencil reification+--+-- In the AST representation, we turn the stencil type from nested tuples of Accelerate expressions+-- into an Accelerate expression whose type is a tuple nested in the same manner. This enables us+-- to represent the stencil function as a unary function (which also only needs one de Bruijn+-- index). The various positions in the stencil are accessed via tuple indices (i.e., projections).+--+class (Elt (StencilRepr sh stencil), AST.Stencil sh a (StencilRepr sh stencil)) => Stencil sh a stencil where+ type StencilRepr sh stencil :: *+ stencilPrj :: {-dummy-} sh+ -> {-dummy-} a+ -> Exp (StencilRepr sh stencil)+ -> stencil++-- DIM1+instance Elt e => Stencil DIM1 e (Exp e, Exp e, Exp e) where+ type StencilRepr DIM1 (Exp e, Exp e, Exp e)+ = (e, e, e)+ stencilPrj _ _ s = (Exp $ Prj tix2 s,+ Exp $ Prj tix1 s,+ Exp $ Prj tix0 s)++instance Elt e => Stencil DIM1 e (Exp e, Exp e, Exp e, Exp e, Exp e) where+ type StencilRepr DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e)+ = (e, e, e, e, e)+ stencilPrj _ _ s = (Exp $ Prj tix4 s,+ Exp $ Prj tix3 s,+ Exp $ Prj tix2 s,+ Exp $ Prj tix1 s,+ Exp $ Prj tix0 s)++instance Elt e => Stencil DIM1 e (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e) where+ type StencilRepr DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e)+ = (e, e, e, e, e, e, e)+ stencilPrj _ _ s = (Exp $ Prj tix6 s,+ Exp $ Prj tix5 s,+ Exp $ Prj tix4 s,+ Exp $ Prj tix3 s,+ Exp $ Prj tix2 s,+ Exp $ Prj tix1 s,+ Exp $ Prj tix0 s)++instance Elt e => Stencil DIM1 e (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e)+ where+ type StencilRepr DIM1 (Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e, Exp e)+ = (e, e, e, e, e, e, e, e, e)+ stencilPrj _ _ s = (Exp $ Prj tix8 s,+ Exp $ Prj tix7 s,+ Exp $ Prj tix6 s,+ Exp $ Prj tix5 s,+ Exp $ Prj tix4 s,+ Exp $ Prj tix3 s,+ Exp $ Prj tix2 s,+ Exp $ Prj tix1 s,+ Exp $ Prj tix0 s)++-- DIM(n+1)+instance (Stencil (sh:.Int) a row2,+ Stencil (sh:.Int) a row1,+ Stencil (sh:.Int) a row0) => Stencil (sh:.Int:.Int) a (row2, row1, row0) where+ type StencilRepr (sh:.Int:.Int) (row2, row1, row0)+ = (StencilRepr (sh:.Int) row2, StencilRepr (sh:.Int) row1, StencilRepr (sh:.Int) row0)+ stencilPrj _ a s = (stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix2 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix1 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix0 s))++instance (Stencil (sh:.Int) a row1,+ Stencil (sh:.Int) a row2,+ Stencil (sh:.Int) a row3,+ Stencil (sh:.Int) a row4,+ Stencil (sh:.Int) a row5) => Stencil (sh:.Int:.Int) a (row1, row2, row3, row4, row5) where+ type StencilRepr (sh:.Int:.Int) (row1, row2, row3, row4, row5)+ = (StencilRepr (sh:.Int) row1, StencilRepr (sh:.Int) row2, StencilRepr (sh:.Int) row3,+ StencilRepr (sh:.Int) row4, StencilRepr (sh:.Int) row5)+ stencilPrj _ a s = (stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix4 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix3 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix2 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix1 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix0 s))++instance (Stencil (sh:.Int) a row1,+ Stencil (sh:.Int) a row2,+ Stencil (sh:.Int) a row3,+ Stencil (sh:.Int) a row4,+ Stencil (sh:.Int) a row5,+ Stencil (sh:.Int) a row6,+ Stencil (sh:.Int) a row7)+ => Stencil (sh:.Int:.Int) a (row1, row2, row3, row4, row5, row6, row7) where+ type StencilRepr (sh:.Int:.Int) (row1, row2, row3, row4, row5, row6, row7)+ = (StencilRepr (sh:.Int) row1, StencilRepr (sh:.Int) row2, StencilRepr (sh:.Int) row3,+ StencilRepr (sh:.Int) row4, StencilRepr (sh:.Int) row5, StencilRepr (sh:.Int) row6,+ StencilRepr (sh:.Int) row7)+ stencilPrj _ a s = (stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix6 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix5 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix4 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix3 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix2 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix1 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix0 s))++instance (Stencil (sh:.Int) a row1,+ Stencil (sh:.Int) a row2,+ Stencil (sh:.Int) a row3,+ Stencil (sh:.Int) a row4,+ Stencil (sh:.Int) a row5,+ Stencil (sh:.Int) a row6,+ Stencil (sh:.Int) a row7,+ Stencil (sh:.Int) a row8,+ Stencil (sh:.Int) a row9)+ => Stencil (sh:.Int:.Int) a (row1, row2, row3, row4, row5, row6, row7, row8, row9) where+ type StencilRepr (sh:.Int:.Int) (row1, row2, row3, row4, row5, row6, row7, row8, row9)+ = (StencilRepr (sh:.Int) row1, StencilRepr (sh:.Int) row2, StencilRepr (sh:.Int) row3,+ StencilRepr (sh:.Int) row4, StencilRepr (sh:.Int) row5, StencilRepr (sh:.Int) row6,+ StencilRepr (sh:.Int) row7, StencilRepr (sh:.Int) row8, StencilRepr (sh:.Int) row9)+ stencilPrj _ a s = (stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix8 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix7 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix6 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix5 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix4 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix3 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix2 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix1 s),+ stencilPrj (undefined::(sh:.Int)) a (Exp $ Prj tix0 s))++-- Auxiliary tuple index constants+--+tix0 :: TupleIdx (t, s0) s0+tix0 = ZeroTupIdx++tix1 :: TupleIdx ((t, s1), s0) s1+tix1 = SuccTupIdx tix0++tix2 :: TupleIdx (((t, s2), s1), s0) s2+tix2 = SuccTupIdx tix1++tix3 :: TupleIdx ((((t, s3), s2), s1), s0) s3+tix3 = SuccTupIdx tix2++tix4 :: TupleIdx (((((t, s4), s3), s2), s1), s0) s4+tix4 = SuccTupIdx tix3++tix5 :: TupleIdx ((((((t, s5), s4), s3), s2), s1), s0) s5+tix5 = SuccTupIdx tix4++tix6 :: TupleIdx (((((((t, s6), s5), s4), s3), s2), s1), s0) s6+tix6 = SuccTupIdx tix5++tix7 :: TupleIdx ((((((((t, s7), s6), s5), s4), s3), s2), s1), s0) s7+tix7 = SuccTupIdx tix6++tix8 :: TupleIdx (((((((((t, s8), s7), s6), s5), s4), s3), s2), s1), s0) s8+tix8 = SuccTupIdx tix7++tix9 :: TupleIdx ((((((((((t, s9), s8), s7), s6), s5), s4), s3), s2), s1), s0) s9+tix9 = SuccTupIdx tix8++tix10 :: TupleIdx (((((((((((t, s10), s9), s8), s7), s6), s5), s4), s3), s2), s1), s0) s10+tix10 = SuccTupIdx tix9++tix11 :: TupleIdx ((((((((((((t, s11), s10), s9), s8), s7), s6), s5), s4), s3), s2), s1), s0) s11+tix11 = SuccTupIdx tix10++tix12 :: TupleIdx (((((((((((((t, s12), s11), s10), s9), s8), s7), s6), s5), s4), s3), s2), s1), s0) s12+tix12 = SuccTupIdx tix11++tix13 :: TupleIdx ((((((((((((((t, s13), s12), s11), s10), s9), s8), s7), s6), s5), s4), s3), s2), s1), s0) s13+tix13 = SuccTupIdx tix12++tix14 :: TupleIdx (((((((((((((((t, s14), s13), s12), s11), s10), s9), s8), s7), s6), s5), s4), s3), s2), s1), s0) s14+tix14 = SuccTupIdx tix13++{--+-- Smart constructors for array tuples in sequence computations+-- ---------------------------------------------------++stup2 :: (Arrays a, Arrays b) => (Seq a, Seq b) -> Seq (a, b)+stup2 (a, b) = Seq $ Stuple (NilAtup `SnocAtup` a `SnocAtup` b)++stup3 :: (Arrays a, Arrays b, Arrays c) => (Seq a, Seq b, Seq c) -> Seq (a, b, c)+stup3 (a, b, c) = Seq $ Stuple (NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c)++stup4 :: (Arrays a, Arrays b, Arrays c, Arrays d)+ => (Seq a, Seq b, Seq c, Seq d) -> Seq (a, b, c, d)+stup4 (a, b, c, d)+ = Seq $ Stuple (NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d)++stup5 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e)+ => (Seq a, Seq b, Seq c, Seq d, Seq e) -> Seq (a, b, c, d, e)+stup5 (a, b, c, d, e)+ = Seq $ Stuple $+ NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e++stup6 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f)+ => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f) -> Seq (a, b, c, d, e, f)+stup6 (a, b, c, d, e, f)+ = Seq $ Stuple $+ NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c+ `SnocAtup` d `SnocAtup` e `SnocAtup` f++stup7 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g)+ => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g)+ -> Seq (a, b, c, d, e, f, g)+stup7 (a, b, c, d, e, f, g)+ = Seq $ Stuple $+ NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c+ `SnocAtup` d `SnocAtup` e `SnocAtup` f `SnocAtup` g++stup8 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h)+ => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g, Seq h)+ -> Seq (a, b, c, d, e, f, g, h)+stup8 (a, b, c, d, e, f, g, h)+ = Seq $ Stuple $+ NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d+ `SnocAtup` e `SnocAtup` f `SnocAtup` g `SnocAtup` h++stup9 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i)+ => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g, Seq h, Seq i)+ -> Seq (a, b, c, d, e, f, g, h, i)+stup9 (a, b, c, d, e, f, g, h, i)+ = Seq $ Stuple $+ NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d+ `SnocAtup` e `SnocAtup` f `SnocAtup` g `SnocAtup` h `SnocAtup` i++stup10 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j)+ => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g, Seq h, Seq i, Seq j)+ -> Seq (a, b, c, d, e, f, g, h, i, j)+stup10 (a, b, c, d, e, f, g, h, i, j)+ = Seq $ Stuple $+ NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e+ `SnocAtup` f `SnocAtup` g `SnocAtup` h `SnocAtup` i `SnocAtup` j++stup11 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k)+ => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g, Seq h, Seq i, Seq j, Seq k)+ -> Seq (a, b, c, d, e, f, g, h, i, j, k)+stup11 (a, b, c, d, e, f, g, h, i, j, k)+ = Seq $ Stuple $+ NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e+ `SnocAtup` f `SnocAtup` g `SnocAtup` h `SnocAtup` i `SnocAtup` j `SnocAtup` k++stup12 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l)+ => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g, Seq h, Seq i, Seq j, Seq k, Seq l)+ -> Seq (a, b, c, d, e, f, g, h, i, j, k, l)+stup12 (a, b, c, d, e, f, g, h, i, j, k, l)+ = Seq $ Stuple $+ NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e `SnocAtup` f+ `SnocAtup` g `SnocAtup` h `SnocAtup` i `SnocAtup` j `SnocAtup` k `SnocAtup` l++stup13 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m)+ => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g, Seq h, Seq i, Seq j, Seq k, Seq l, Seq m)+ -> Seq (a, b, c, d, e, f, g, h, i, j, k, l, m)+stup13 (a, b, c, d, e, f, g, h, i, j, k, l, m)+ = Seq $ Stuple $+ NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e `SnocAtup` f+ `SnocAtup` g `SnocAtup` h `SnocAtup` i `SnocAtup` j `SnocAtup` k `SnocAtup` l `SnocAtup` m++stup14 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m, Arrays n)+ => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g, Seq h, Seq i, Seq j, Seq k, Seq l, Seq m, Seq n)+ -> Seq (a, b, c, d, e, f, g, h, i, j, k, l, m, n)+stup14 (a, b, c, d, e, f, g, h, i, j, k, l, m, n)+ = Seq $ Stuple $+ NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e `SnocAtup` f `SnocAtup` g+ `SnocAtup` h `SnocAtup` i `SnocAtup` j `SnocAtup` k `SnocAtup` l `SnocAtup` m `SnocAtup` n++stup15 :: (Arrays a, Arrays b, Arrays c, Arrays d, Arrays e, Arrays f, Arrays g, Arrays h, Arrays i, Arrays j, Arrays k, Arrays l, Arrays m, Arrays n, Arrays o)+ => (Seq a, Seq b, Seq c, Seq d, Seq e, Seq f, Seq g, Seq h, Seq i, Seq j, Seq k, Seq l, Seq m, Seq n, Seq o)+ -> Seq (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)+stup15 (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)+ = Seq $ Stuple $+ NilAtup `SnocAtup` a `SnocAtup` b `SnocAtup` c `SnocAtup` d `SnocAtup` e `SnocAtup` f `SnocAtup` g+ `SnocAtup` h `SnocAtup` i `SnocAtup` j `SnocAtup` k `SnocAtup` l `SnocAtup` m `SnocAtup` n `SnocAtup` o+--}++-- Smart constructor for literals+--++-- | Scalar expression inlet: make a Haskell value available for processing in+-- an Accelerate scalar expression.+--+-- Note that this embeds the value directly into the expression. Depending on+-- the backend used to execute the computation, this might not always be+-- desirable. For example, a backend that does external code generation may+-- embed this constant directly into the generated code, which means new code+-- will need to be generated and compiled every time the value changes. In such+-- cases, consider instead lifting scalar values into (singleton) arrays so that+-- they can be passed as an input to the computation and thus the value can+-- change without the need to generate fresh code.+--+constant :: Elt t => t -> Exp t+constant = Exp . Const++-- Smart constructor and destructors for scalar tuples+--+tup2 :: (Elt a, Elt b) => (Exp a, Exp b) -> Exp (a, b)+tup2 (a, b)+ = Exp+ $ Tuple+ $ NilTup `SnocTup` a+ `SnocTup` b++tup3 :: (Elt a, Elt b, Elt c)+ => (Exp a, Exp b, Exp c)+ -> Exp (a, b, c)+tup3 (a, b, c)+ = Exp+ $ Tuple+ $ NilTup `SnocTup` a+ `SnocTup` b+ `SnocTup` c++tup4 :: (Elt a, Elt b, Elt c, Elt d)+ => (Exp a, Exp b, Exp c, Exp d)+ -> Exp (a, b, c, d)+tup4 (a, b, c, d)+ = Exp+ $ Tuple+ $ NilTup `SnocTup` a+ `SnocTup` b+ `SnocTup` c+ `SnocTup` d++tup5 :: (Elt a, Elt b, Elt c, Elt d, Elt e)+ => (Exp a, Exp b, Exp c, Exp d, Exp e)+ -> Exp (a, b, c, d, e)+tup5 (a, b, c, d, e)+ = Exp+ $ Tuple+ $ NilTup `SnocTup` a+ `SnocTup` b+ `SnocTup` c+ `SnocTup` d+ `SnocTup` e++tup6 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f)+ => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f)+ -> Exp (a, b, c, d, e, f)+tup6 (a, b, c, d, e, f)+ = Exp+ $ Tuple+ $ NilTup `SnocTup` a+ `SnocTup` b+ `SnocTup` c+ `SnocTup` d+ `SnocTup` e+ `SnocTup` f++tup7 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g)+ => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g)+ -> Exp (a, b, c, d, e, f, g)+tup7 (a, b, c, d, e, f, g)+ = Exp+ $ Tuple+ $ NilTup `SnocTup` a+ `SnocTup` b+ `SnocTup` c+ `SnocTup` d+ `SnocTup` e+ `SnocTup` f+ `SnocTup` g++tup8 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h)+ => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h)+ -> Exp (a, b, c, d, e, f, g, h)+tup8 (a, b, c, d, e, f, g, h)+ = Exp+ $ Tuple+ $ NilTup `SnocTup` a+ `SnocTup` b+ `SnocTup` c+ `SnocTup` d+ `SnocTup` e+ `SnocTup` f+ `SnocTup` g+ `SnocTup` h++tup9 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i)+ => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i)+ -> Exp (a, b, c, d, e, f, g, h, i)+tup9 (a, b, c, d, e, f, g, h, i)+ = Exp+ $ Tuple+ $ NilTup `SnocTup` a+ `SnocTup` b+ `SnocTup` c+ `SnocTup` d+ `SnocTup` e+ `SnocTup` f+ `SnocTup` g+ `SnocTup` h+ `SnocTup` i++tup10 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j)+ => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j)+ -> Exp (a, b, c, d, e, f, g, h, i, j)+tup10 (a, b, c, d, e, f, g, h, i, j)+ = Exp+ $ Tuple+ $ NilTup `SnocTup` a+ `SnocTup` b+ `SnocTup` c+ `SnocTup` d+ `SnocTup` e+ `SnocTup` f+ `SnocTup` g+ `SnocTup` h+ `SnocTup` i+ `SnocTup` j++tup11 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k)+ => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k)+ -> Exp (a, b, c, d, e, f, g, h, i, j, k)+tup11 (a, b, c, d, e, f, g, h, i, j, k)+ = Exp+ $ Tuple+ $ NilTup `SnocTup` a+ `SnocTup` b+ `SnocTup` c+ `SnocTup` d+ `SnocTup` e+ `SnocTup` f+ `SnocTup` g+ `SnocTup` h+ `SnocTup` i+ `SnocTup` j+ `SnocTup` k++tup12 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l)+ => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k, Exp l)+ -> Exp (a, b, c, d, e, f, g, h, i, j, k, l)+tup12 (a, b, c, d, e, f, g, h, i, j, k, l)+ = Exp+ $ Tuple+ $ NilTup `SnocTup` a+ `SnocTup` b+ `SnocTup` c+ `SnocTup` d+ `SnocTup` e+ `SnocTup` f+ `SnocTup` g+ `SnocTup` h+ `SnocTup` i+ `SnocTup` j+ `SnocTup` k+ `SnocTup` l++tup13 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l, Elt m)+ => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k, Exp l, Exp m)+ -> Exp (a, b, c, d, e, f, g, h, i, j, k, l, m)+tup13 (a, b, c, d, e, f, g, h, i, j, k, l, m)+ = Exp+ $ Tuple+ $ NilTup `SnocTup` a+ `SnocTup` b+ `SnocTup` c+ `SnocTup` d+ `SnocTup` e+ `SnocTup` f+ `SnocTup` g+ `SnocTup` h+ `SnocTup` i+ `SnocTup` j+ `SnocTup` k+ `SnocTup` l+ `SnocTup` m++tup14 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l, Elt m, Elt n)+ => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k, Exp l, Exp m, Exp n)+ -> Exp (a, b, c, d, e, f, g, h, i, j, k, l, m, n)+tup14 (a, b, c, d, e, f, g, h, i, j, k, l, m, n)+ = Exp+ $ Tuple+ $ NilTup `SnocTup` a+ `SnocTup` b+ `SnocTup` c+ `SnocTup` d+ `SnocTup` e+ `SnocTup` f+ `SnocTup` g+ `SnocTup` h+ `SnocTup` i+ `SnocTup` j+ `SnocTup` k+ `SnocTup` l+ `SnocTup` m+ `SnocTup` n++tup15 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l, Elt m, Elt n, Elt o)+ => (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k, Exp l, Exp m, Exp n, Exp o)+ -> Exp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)+tup15 (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)+ = Exp+ $ Tuple+ $ NilTup `SnocTup` a+ `SnocTup` b+ `SnocTup` c+ `SnocTup` d+ `SnocTup` e+ `SnocTup` f+ `SnocTup` g+ `SnocTup` h+ `SnocTup` i+ `SnocTup` j+ `SnocTup` k+ `SnocTup` l+ `SnocTup` m+ `SnocTup` n+ `SnocTup` o++untup2 :: (Elt a, Elt b) => Exp (a, b) -> (Exp a, Exp b)+untup2 e =+ ( Exp $ tix1 `Prj` e+ , Exp $ tix0 `Prj` e )++untup3 :: (Elt a, Elt b, Elt c) => Exp (a, b, c) -> (Exp a, Exp b, Exp c)+untup3 e =+ ( Exp $ tix2 `Prj` e+ , Exp $ tix1 `Prj` e+ , Exp $ tix0 `Prj` e )++untup4 :: (Elt a, Elt b, Elt c, Elt d)+ => Exp (a, b, c, d)+ -> (Exp a, Exp b, Exp c, Exp d)+untup4 e =+ ( Exp $ tix3 `Prj` e+ , Exp $ tix2 `Prj` e+ , Exp $ tix1 `Prj` e+ , Exp $ tix0 `Prj` e )++untup5 :: (Elt a, Elt b, Elt c, Elt d, Elt e)+ => Exp (a, b, c, d, e)+ -> (Exp a, Exp b, Exp c, Exp d, Exp e)+untup5 e =+ ( Exp $ tix4 `Prj` e+ , Exp $ tix3 `Prj` e+ , Exp $ tix2 `Prj` e+ , Exp $ tix1 `Prj` e+ , Exp $ tix0 `Prj` e )++untup6 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f)+ => Exp (a, b, c, d, e, f)+ -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f)+untup6 e =+ ( Exp $ tix5 `Prj` e+ , Exp $ tix4 `Prj` e+ , Exp $ tix3 `Prj` e+ , Exp $ tix2 `Prj` e+ , Exp $ tix1 `Prj` e+ , Exp $ tix0 `Prj` e )++untup7 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g)+ => Exp (a, b, c, d, e, f, g)+ -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g)+untup7 e =+ ( Exp $ tix6 `Prj` e+ , Exp $ tix5 `Prj` e+ , Exp $ tix4 `Prj` e+ , Exp $ tix3 `Prj` e+ , Exp $ tix2 `Prj` e+ , Exp $ tix1 `Prj` e+ , Exp $ tix0 `Prj` e )++untup8 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h)+ => Exp (a, b, c, d, e, f, g, h)+ -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h)+untup8 e =+ ( Exp $ tix7 `Prj` e+ , Exp $ tix6 `Prj` e+ , Exp $ tix5 `Prj` e+ , Exp $ tix4 `Prj` e+ , Exp $ tix3 `Prj` e+ , Exp $ tix2 `Prj` e+ , Exp $ tix1 `Prj` e+ , Exp $ tix0 `Prj` e )++untup9 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i)+ => Exp (a, b, c, d, e, f, g, h, i)+ -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i)+untup9 e =+ ( Exp $ tix8 `Prj` e+ , Exp $ tix7 `Prj` e+ , Exp $ tix6 `Prj` e+ , Exp $ tix5 `Prj` e+ , Exp $ tix4 `Prj` e+ , Exp $ tix3 `Prj` e+ , Exp $ tix2 `Prj` e+ , Exp $ tix1 `Prj` e+ , Exp $ tix0 `Prj` e )++untup10 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j)+ => Exp (a, b, c, d, e, f, g, h, i, j)+ -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j)+untup10 e =+ ( Exp $ tix9 `Prj` e+ , Exp $ tix8 `Prj` e+ , Exp $ tix7 `Prj` e+ , Exp $ tix6 `Prj` e+ , Exp $ tix5 `Prj` e+ , Exp $ tix4 `Prj` e+ , Exp $ tix3 `Prj` e+ , Exp $ tix2 `Prj` e+ , Exp $ tix1 `Prj` e+ , Exp $ tix0 `Prj` e )++untup11 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k)+ => Exp (a, b, c, d, e, f, g, h, i, j, k)+ -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k)+untup11 e =+ ( Exp $ tix10 `Prj` e+ , Exp $ tix9 `Prj` e+ , Exp $ tix8 `Prj` e+ , Exp $ tix7 `Prj` e+ , Exp $ tix6 `Prj` e+ , Exp $ tix5 `Prj` e+ , Exp $ tix4 `Prj` e+ , Exp $ tix3 `Prj` e+ , Exp $ tix2 `Prj` e+ , Exp $ tix1 `Prj` e+ , Exp $ tix0 `Prj` e )++untup12 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l)+ => Exp (a, b, c, d, e, f, g, h, i, j, k, l)+ -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k, Exp l)+untup12 e =+ ( Exp $ tix11 `Prj` e+ , Exp $ tix10 `Prj` e+ , Exp $ tix9 `Prj` e+ , Exp $ tix8 `Prj` e+ , Exp $ tix7 `Prj` e+ , Exp $ tix6 `Prj` e+ , Exp $ tix5 `Prj` e+ , Exp $ tix4 `Prj` e+ , Exp $ tix3 `Prj` e+ , Exp $ tix2 `Prj` e+ , Exp $ tix1 `Prj` e+ , Exp $ tix0 `Prj` e )++untup13 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l, Elt m)+ => Exp (a, b, c, d, e, f, g, h, i, j, k, l, m)+ -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k, Exp l, Exp m)+untup13 e =+ ( Exp $ tix12 `Prj` e+ , Exp $ tix11 `Prj` e+ , Exp $ tix10 `Prj` e+ , Exp $ tix9 `Prj` e+ , Exp $ tix8 `Prj` e+ , Exp $ tix7 `Prj` e+ , Exp $ tix6 `Prj` e+ , Exp $ tix5 `Prj` e+ , Exp $ tix4 `Prj` e+ , Exp $ tix3 `Prj` e+ , Exp $ tix2 `Prj` e+ , Exp $ tix1 `Prj` e+ , Exp $ tix0 `Prj` e )++untup14 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l, Elt m, Elt n)+ => Exp (a, b, c, d, e, f, g, h, i, j, k, l, m, n)+ -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k, Exp l, Exp m, Exp n)+untup14 e =+ ( Exp $ tix13 `Prj` e+ , Exp $ tix12 `Prj` e+ , Exp $ tix11 `Prj` e+ , Exp $ tix10 `Prj` e+ , Exp $ tix9 `Prj` e+ , Exp $ tix8 `Prj` e+ , Exp $ tix7 `Prj` e+ , Exp $ tix6 `Prj` e+ , Exp $ tix5 `Prj` e+ , Exp $ tix4 `Prj` e+ , Exp $ tix3 `Prj` e+ , Exp $ tix2 `Prj` e+ , Exp $ tix1 `Prj` e+ , Exp $ tix0 `Prj` e )++untup15 :: (Elt a, Elt b, Elt c, Elt d, Elt e, Elt f, Elt g, Elt h, Elt i, Elt j, Elt k, Elt l, Elt m, Elt n, Elt o)+ => Exp (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)+ -> (Exp a, Exp b, Exp c, Exp d, Exp e, Exp f, Exp g, Exp h, Exp i, Exp j, Exp k, Exp l, Exp m, Exp n, Exp o)+untup15 e =+ ( Exp $ tix14 `Prj` e+ , Exp $ tix13 `Prj` e+ , Exp $ tix12 `Prj` e+ , Exp $ tix11 `Prj` e+ , Exp $ tix10 `Prj` e+ , Exp $ tix9 `Prj` e+ , Exp $ tix8 `Prj` e+ , Exp $ tix7 `Prj` e+ , Exp $ tix6 `Prj` e+ , Exp $ tix5 `Prj` e+ , Exp $ tix4 `Prj` e+ , Exp $ tix3 `Prj` e+ , Exp $ tix2 `Prj` e+ , Exp $ tix1 `Prj` e+ , Exp $ tix0 `Prj` e )+++-- Smart constructor for constants+--++mkMinBound :: (Elt t, IsBounded t) => Exp t+mkMinBound = Exp $ PrimConst (PrimMinBound boundedType)++mkMaxBound :: (Elt t, IsBounded t) => Exp t+mkMaxBound = Exp $ PrimConst (PrimMaxBound boundedType)++mkPi :: (Elt r, IsFloating r) => Exp r+mkPi = Exp $ PrimConst (PrimPi floatingType)+++-- Smart constructors for primitive applications+--++-- Operators from Floating++mkSin :: (Elt t, IsFloating t) => Exp t -> Exp t+mkSin x = Exp $ PrimSin floatingType `PrimApp` x++mkCos :: (Elt t, IsFloating t) => Exp t -> Exp t+mkCos x = Exp $ PrimCos floatingType `PrimApp` x++mkTan :: (Elt t, IsFloating t) => Exp t -> Exp t+mkTan x = Exp $ PrimTan floatingType `PrimApp` x++mkAsin :: (Elt t, IsFloating t) => Exp t -> Exp t+mkAsin x = Exp $ PrimAsin floatingType `PrimApp` x++mkAcos :: (Elt t, IsFloating t) => Exp t -> Exp t+mkAcos x = Exp $ PrimAcos floatingType `PrimApp` x++mkAtan :: (Elt t, IsFloating t) => Exp t -> Exp t+mkAtan x = Exp $ PrimAtan floatingType `PrimApp` x++mkSinh :: (Elt t, IsFloating t) => Exp t -> Exp t+mkSinh x = Exp $ PrimSinh floatingType `PrimApp` x++mkCosh :: (Elt t, IsFloating t) => Exp t -> Exp t+mkCosh x = Exp $ PrimCosh floatingType `PrimApp` x++mkTanh :: (Elt t, IsFloating t) => Exp t -> Exp t+mkTanh x = Exp $ PrimTanh floatingType `PrimApp` x++mkAsinh :: (Elt t, IsFloating t) => Exp t -> Exp t+mkAsinh x = Exp $ PrimAsinh floatingType `PrimApp` x++mkAcosh :: (Elt t, IsFloating t) => Exp t -> Exp t+mkAcosh x = Exp $ PrimAcosh floatingType `PrimApp` x++mkAtanh :: (Elt t, IsFloating t) => Exp t -> Exp t+mkAtanh x = Exp $ PrimAtanh floatingType `PrimApp` x++mkExpFloating :: (Elt t, IsFloating t) => Exp t -> Exp t+mkExpFloating x = Exp $ PrimExpFloating floatingType `PrimApp` x++mkSqrt :: (Elt t, IsFloating t) => Exp t -> Exp t+mkSqrt x = Exp $ PrimSqrt floatingType `PrimApp` x++mkLog :: (Elt t, IsFloating t) => Exp t -> Exp t+mkLog x = Exp $ PrimLog floatingType `PrimApp` x++mkFPow :: (Elt t, IsFloating t) => Exp t -> Exp t -> Exp t+mkFPow x y = Exp $ PrimFPow floatingType `PrimApp` tup2 (x, y)++mkLogBase :: (Elt t, IsFloating t) => Exp t -> Exp t -> Exp t+mkLogBase x y = Exp $ PrimLogBase floatingType `PrimApp` tup2 (x, y)++-- Operators from Num++mkAdd :: (Elt t, IsNum t) => Exp t -> Exp t -> Exp t+mkAdd x y = Exp $ PrimAdd numType `PrimApp` tup2 (x, y)++mkSub :: (Elt t, IsNum t) => Exp t -> Exp t -> Exp t+mkSub x y = Exp $ PrimSub numType `PrimApp` tup2 (x, y)++mkMul :: (Elt t, IsNum t) => Exp t -> Exp t -> Exp t+mkMul x y = Exp $ PrimMul numType `PrimApp` tup2 (x, y)++mkNeg :: (Elt t, IsNum t) => Exp t -> Exp t+mkNeg x = Exp $ PrimNeg numType `PrimApp` x++mkAbs :: (Elt t, IsNum t) => Exp t -> Exp t+mkAbs x = Exp $ PrimAbs numType `PrimApp` x++mkSig :: (Elt t, IsNum t) => Exp t -> Exp t+mkSig x = Exp $ PrimSig numType `PrimApp` x++-- Operators from Integral++mkQuot :: (Elt t, IsIntegral t) => Exp t -> Exp t -> Exp t+mkQuot x y = Exp $ PrimQuot integralType `PrimApp` tup2 (x, y)++mkRem :: (Elt t, IsIntegral t) => Exp t -> Exp t -> Exp t+mkRem x y = Exp $ PrimRem integralType `PrimApp` tup2 (x, y)++mkQuotRem :: (Elt t, IsIntegral t) => Exp t -> Exp t -> (Exp t, Exp t)+mkQuotRem x y = untup2 $ Exp $ PrimQuotRem integralType `PrimApp` tup2 (x ,y)++mkIDiv :: (Elt t, IsIntegral t) => Exp t -> Exp t -> Exp t+mkIDiv x y = Exp $ PrimIDiv integralType `PrimApp` tup2 (x, y)++mkMod :: (Elt t, IsIntegral t) => Exp t -> Exp t -> Exp t+mkMod x y = Exp $ PrimMod integralType `PrimApp` tup2 (x, y)++mkDivMod :: (Elt t, IsIntegral t) => Exp t -> Exp t -> (Exp t, Exp t)+mkDivMod x y = untup2 $ Exp $ PrimDivMod integralType `PrimApp` tup2 (x ,y)+++-- Operators from Bits and FiniteBits++mkBAnd :: (Elt t, IsIntegral t) => Exp t -> Exp t -> Exp t+mkBAnd x y = Exp $ PrimBAnd integralType `PrimApp` tup2 (x, y)++mkBOr :: (Elt t, IsIntegral t) => Exp t -> Exp t -> Exp t+mkBOr x y = Exp $ PrimBOr integralType `PrimApp` tup2 (x, y)++mkBXor :: (Elt t, IsIntegral t) => Exp t -> Exp t -> Exp t+mkBXor x y = Exp $ PrimBXor integralType `PrimApp` tup2 (x, y)++mkBNot :: (Elt t, IsIntegral t) => Exp t -> Exp t+mkBNot x = Exp $ PrimBNot integralType `PrimApp` x++mkBShiftL :: (Elt t, IsIntegral t) => Exp t -> Exp Int -> Exp t+mkBShiftL x i = Exp $ PrimBShiftL integralType `PrimApp` tup2 (x, i)++mkBShiftR :: (Elt t, IsIntegral t) => Exp t -> Exp Int -> Exp t+mkBShiftR x i = Exp $ PrimBShiftR integralType `PrimApp` tup2 (x, i)++mkBRotateL :: (Elt t, IsIntegral t) => Exp t -> Exp Int -> Exp t+mkBRotateL x i = Exp $ PrimBRotateL integralType `PrimApp` tup2 (x, i)++mkBRotateR :: (Elt t, IsIntegral t) => Exp t -> Exp Int -> Exp t+mkBRotateR x i = Exp $ PrimBRotateR integralType `PrimApp` tup2 (x, i)++mkPopCount :: (Elt t, IsIntegral t) => Exp t -> Exp Int+mkPopCount x = Exp $ PrimPopCount integralType `PrimApp` x++mkCountLeadingZeros :: (Elt t, IsIntegral t) => Exp t -> Exp Int+mkCountLeadingZeros x = Exp $ PrimCountLeadingZeros integralType `PrimApp` x++mkCountTrailingZeros :: (Elt t, IsIntegral t) => Exp t -> Exp Int+mkCountTrailingZeros x = Exp $ PrimCountTrailingZeros integralType `PrimApp` x+++-- Operators from Fractional++mkFDiv :: (Elt t, IsFloating t) => Exp t -> Exp t -> Exp t+mkFDiv x y = Exp $ PrimFDiv floatingType `PrimApp` tup2 (x, y)++mkRecip :: (Elt t, IsFloating t) => Exp t -> Exp t+mkRecip x = Exp $ PrimRecip floatingType `PrimApp` x++-- Operators from RealFrac++mkTruncate :: (Elt a, Elt b, IsFloating a, IsIntegral b) => Exp a -> Exp b+mkTruncate x = Exp $ PrimTruncate floatingType integralType `PrimApp` x++mkRound :: (Elt a, Elt b, IsFloating a, IsIntegral b) => Exp a -> Exp b+mkRound x = Exp $ PrimRound floatingType integralType `PrimApp` x++mkFloor :: (Elt a, Elt b, IsFloating a, IsIntegral b) => Exp a -> Exp b+mkFloor x = Exp $ PrimFloor floatingType integralType `PrimApp` x++mkCeiling :: (Elt a, Elt b, IsFloating a, IsIntegral b) => Exp a -> Exp b+mkCeiling x = Exp $ PrimCeiling floatingType integralType `PrimApp` x++-- Operators from RealFloat++mkAtan2 :: (Elt t, IsFloating t) => Exp t -> Exp t -> Exp t+mkAtan2 x y = Exp $ PrimAtan2 floatingType `PrimApp` tup2 (x, y)++mkIsNaN :: (Elt t, IsFloating t) => Exp t -> Exp Bool+mkIsNaN x = Exp $ PrimIsNaN floatingType `PrimApp` x++mkIsInfinite :: (Elt t, IsFloating t) => Exp t -> Exp Bool+mkIsInfinite x = Exp $ PrimIsInfinite floatingType `PrimApp` x -- FIXME: add missing operations from Floating, RealFrac & RealFloat
Data/Array/Accelerate/Trafo.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MonoLocalBinds #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE UndecidableInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-}@@ -20,10 +21,16 @@ -- * HOAS -> de Bruijn conversion Phase(..), phases, - convertAcc, convertAccWith,+ -- ** Array computations+ convertAcc, convertAccWith,++ -- ** Array functions+ Afunction, AfunctionR, convertAfun, convertAfunWith,- -- convertSeq, convertSeqWith, + -- ** Sequence computations+ -- convertSeq, convertSeqWith,+ -- * Fusion module Data.Array.Accelerate.Trafo.Fusion, -- DelayedSeq(..), Extend(..),@@ -33,6 +40,9 @@ -- * Term equality Match(..), (:~:)(..),++ -- ** Auxiliary+ matchDelayedOpenAcc, hashDelayedOpenAcc, ) where
Data/Array/Accelerate/Trafo/Algebra.hs view
@@ -147,6 +147,7 @@ PrimFloor ta tb -> evalFloor ta tb x env PrimCeiling ta tb -> evalCeiling ta tb x env PrimIsNaN ty -> evalIsNaN ty x env+ PrimIsInfinite ty -> evalIsInfinite ty x env PrimLt ty -> evalLt ty x env PrimGt ty -> evalGt ty x env PrimLtEq ty -> evalLtEq ty x env@@ -601,6 +602,9 @@ evalIsNaN :: FloatingType a -> a :-> Bool evalIsNaN ty | FloatingDict <- floatingDict ty = eval1 isNaN++evalIsInfinite :: FloatingType a -> a :-> Bool+evalIsInfinite ty | FloatingDict <- floatingDict ty = eval1 isInfinite -- Relational & Equality
Data/Array/Accelerate/Trafo/Base.hs view
@@ -36,6 +36,7 @@ DelayedAfun, DelayedOpenAfun, DelayedExp, DelayedFun, DelayedOpenExp, DelayedOpenFun, -- DelayedSeq(..), DelayedOpenSeq,+ matchDelayedOpenAcc, hashDelayedOpenAcc, -- Environments Gamma(..), incExp, prjExp, lookupExp,@@ -57,6 +58,7 @@ -- friends import Data.Array.Accelerate.AST hiding ( Val(..) )+import Data.Array.Accelerate.Analysis.Hash import Data.Array.Accelerate.Analysis.Match import Data.Array.Accelerate.Array.Sugar ( Array, Arrays, Shape, Elt ) import Data.Array.Accelerate.Error@@ -183,9 +185,9 @@ {-# INLINEABLE hashAcc #-} {-# INLINEABLE matchAcc #-} {-# INLINEABLE prettyAcc #-}- hashAcc = hashDelayed- matchAcc = matchDelayed- prettyAcc = prettyDelayed+ hashAcc = hashDelayedOpenAcc+ matchAcc = matchDelayedOpenAcc+ prettyAcc = prettyDelayedOpenAcc instance NFData (DelayedOpenAfun aenv t) where rnf = rnfPreOpenAfun rnfDelayedOpenAcc@@ -196,24 +198,24 @@ -- instance NFData (DelayedSeq t) where -- rnf = rnfDelayedSeq -hashDelayed :: HashAcc DelayedOpenAcc-hashDelayed (Manifest pacc) = hash "Manifest" `hashWithSalt` hashPreOpenAcc hashAcc pacc-hashDelayed Delayed{..} = hash "Delayed" `hashE` extentD `hashF` indexD `hashF` linearIndexD+hashDelayedOpenAcc :: HashAcc DelayedOpenAcc+hashDelayedOpenAcc (Manifest pacc) = $(hashQ "Manifest") `hashWithSalt` hashPreOpenAcc hashAcc pacc+hashDelayedOpenAcc Delayed{..} = $(hashQ "Delayed") `hashE` extentD `hashF` indexD `hashF` linearIndexD where hashE salt = hashWithSalt salt . hashPreOpenExp hashAcc hashF salt = hashWithSalt salt . hashPreOpenFun hashAcc -matchDelayed :: MatchAcc DelayedOpenAcc-matchDelayed (Manifest pacc1) (Manifest pacc2)+matchDelayedOpenAcc :: MatchAcc DelayedOpenAcc+matchDelayedOpenAcc (Manifest pacc1) (Manifest pacc2) = matchPreOpenAcc matchAcc hashAcc pacc1 pacc2 -matchDelayed (Delayed sh1 ix1 lx1) (Delayed sh2 ix2 lx2)+matchDelayedOpenAcc (Delayed sh1 ix1 lx1) (Delayed sh2 ix2 lx2) | Just Refl <- matchPreOpenExp matchAcc hashAcc sh1 sh2 , Just Refl <- matchPreOpenFun matchAcc hashAcc ix1 ix2 , Just Refl <- matchPreOpenFun matchAcc hashAcc lx1 lx2 = Just Refl -matchDelayed _ _+matchDelayedOpenAcc _ _ = Nothing rnfDelayedOpenAcc :: DelayedOpenAcc aenv t -> ()@@ -242,18 +244,18 @@ -- -- > let a0 = <...> in map f a0 ---prettyDelayed :: PrettyAcc DelayedOpenAcc-prettyDelayed wrap aenv acc = case acc of- Manifest pacc -> prettyPreOpenAcc prettyDelayed wrap aenv pacc+prettyDelayedOpenAcc :: PrettyAcc DelayedOpenAcc+prettyDelayedOpenAcc wrap aenv acc = case acc of+ Manifest pacc -> prettyPreOpenAcc prettyDelayedOpenAcc wrap aenv pacc Delayed sh f _ | Shape a <- sh , Just Refl <- match f (Lam (Body (Index a (Var ZeroIdx))))- -> prettyDelayed wrap aenv a+ -> prettyDelayedOpenAcc wrap aenv a | otherwise -> wrap $ hang (text "Delayed") 2- $ sep [ prettyPreExp prettyDelayed parens aenv sh- , parens (prettyPreFun prettyDelayed aenv f)+ $ sep [ prettyPreExp prettyDelayedOpenAcc parens aenv sh+ , parens (prettyPreFun prettyDelayedOpenAcc aenv f) ]
Data/Array/Accelerate/Trafo/Fusion.hs view
@@ -197,8 +197,8 @@ Scanr1 f a -> Scanr1 (cvtF f) (delayed fuseAcc a) Scanr' f z a -> Scanr' (cvtF f) (cvtE z) (delayed fuseAcc a) Permute f d p a -> Permute (cvtF f) (manifest fuseAcc d) (cvtF p) (delayed fuseAcc a)- Stencil f x a -> Stencil (cvtF f) x (manifest fuseAcc a)- Stencil2 f x a y b -> Stencil2 (cvtF f) x (manifest fuseAcc a) y (manifest fuseAcc b)+ Stencil f x a -> Stencil (cvtF f) (cvtB x) (manifest fuseAcc a)+ Stencil2 f x a y b -> Stencil2 (cvtF f) (cvtB x) (manifest fuseAcc a) (cvtB y) (manifest fuseAcc b) -- Collect s -> Collect (cvtS s) where@@ -233,6 +233,13 @@ cvtE :: OpenExp env aenv t -> DelayedOpenExp env aenv t cvtE = convertOpenExp fuseAcc + cvtB :: Boundary aenv t -> PreBoundary DelayedOpenAcc aenv t+ cvtB Clamp = Clamp+ cvtB Mirror = Mirror+ cvtB Wrap = Wrap+ cvtB (Constant v) = Constant v+ cvtB (Function f) = Function (cvtF f)+ convertOpenExp :: Bool -> OpenExp env aenv t -> DelayedOpenExp env aenv t convertOpenExp fuseAcc exp = case exp of@@ -435,8 +442,8 @@ Scanr1 f a -> embed (into Scanr1 (cvtF f)) a Scanr' f z a -> embed (into2 Scanr' (cvtF f) (cvtE z)) a Permute f d p a -> embed2 (into2 permute (cvtF f) (cvtF p)) d a- Stencil f x a -> lift (into (stencil x) (cvtF f)) a- Stencil2 f x a y b -> lift2 (into (stencil2 x y) (cvtF f)) a b+ Stencil f x a -> lift (into2 Stencil (cvtF f) (cvtB x)) a+ Stencil2 f x a y b -> lift2 (into3 stencil2 (cvtF f) (cvtB x) (cvtB y)) a b where -- If fusion is not enabled, force terms to the manifest representation@@ -460,18 +467,24 @@ -- Helpers to shuffle the order of arguments to a constructor -- permute f p d a = Permute f d p a- stencil x f a = Stencil f x a- stencil2 x y f a b = Stencil2 f x a y b+ stencil2 f x y a b = Stencil2 f x a y b -- Conversions for closed scalar functions and expressions. This just -- applies scalar simplifications. --- cvtF :: PreFun acc aenv t -> PreFun acc aenv t+ cvtF :: PreFun acc aenv' t -> PreFun acc aenv' t cvtF = simplify - cvtE :: Elt t =>PreExp acc aenv' t -> PreExp acc aenv' t+ cvtE :: Elt t => PreExp acc aenv' t -> PreExp acc aenv' t cvtE = simplify + cvtB :: PreBoundary acc aenv' t -> PreBoundary acc aenv' t+ cvtB Clamp = Clamp+ cvtB Mirror = Mirror+ cvtB Wrap = Wrap+ cvtB (Constant c) = Constant c+ cvtB (Function f) = Function (cvtF f)+ -- Helpers to embed and fuse delayed terms -- into :: Sink f => (f env' a -> b) -> f env a -> Extend acc env env' -> b@@ -481,6 +494,10 @@ => (f1 env' a -> f2 env' b -> c) -> f1 env a -> f2 env b -> Extend acc env env' -> c into2 op a b env = op (sink env a) (sink env b) + into3 :: (Sink f1, Sink f2, Sink f3)+ => (f1 env' a -> f2 env' b -> f3 env' c -> d) -> f1 env a -> f2 env b -> f3 env c -> Extend acc env env' -> d+ into3 op a b c env = op (sink env a) (sink env b) (sink env c)+ fuse :: Arrays as => (forall aenv'. Extend acc aenv aenv' -> Cunctation acc aenv' as -> Cunctation acc aenv' bs) -> acc aenv as@@ -859,16 +876,16 @@ compute' :: (Kit acc, Arrays arrs) => Cunctation acc aenv arrs -> PreOpenAcc acc aenv arrs compute' cc = case simplify cc of- Done v -> Avar v- Yield sh f -> Generate sh f+ Done v -> Avar v+ Yield sh f -> Generate sh f Step sh p f v- | Just Refl <- match sh (arrayShape v)+ | Just Refl <- match sh (simplify (arrayShape v)) , Just Refl <- isIdentity p- , Just Refl <- isIdentity f -> Avar v- | Just Refl <- match sh (arrayShape v)- , Just Refl <- isIdentity p -> Map f (avarIn v)- | Just Refl <- isIdentity f -> Backpermute sh p (avarIn v)- | otherwise -> Transform sh p f (avarIn v)+ , Just Refl <- isIdentity f -> Avar v+ | Just Refl <- match sh (simplify (arrayShape v))+ , Just Refl <- isIdentity p -> Map f (avarIn v)+ | Just Refl <- isIdentity f -> Backpermute sh p (avarIn v)+ | otherwise -> Transform sh p f (avarIn v) -- Evaluate a delayed computation and tie the recursive knot@@ -1359,8 +1376,8 @@ Scanr1 f a -> Scanr1 (cvtF f) (cvtA a) Scanr' f z a -> Scanr' (cvtF f) (cvtE z) (cvtA a) Permute f d p a -> Permute (cvtF f) (cvtA d) (cvtF p) (cvtA a)- Stencil f x a -> Stencil (cvtF f) x (cvtA a)- Stencil2 f x a y b -> Stencil2 (cvtF f) x (cvtA a) y (cvtA b)+ Stencil f x a -> Stencil (cvtF f) (cvtB x) (cvtA a)+ Stencil2 f x a y b -> Stencil2 (cvtF f) (cvtB x) (cvtA a) (cvtB y) (cvtA b) -- Collect seq -> Collect (cvtSeq seq) where@@ -1372,6 +1389,13 @@ cvtF :: PreFun acc aenv s -> PreFun acc aenv s cvtF = replaceF sh' f' avar++ cvtB :: PreBoundary acc aenv s -> PreBoundary acc aenv s+ cvtB Clamp = Clamp+ cvtB Mirror = Mirror+ cvtB Wrap = Wrap+ cvtB (Constant c) = Constant c+ cvtB (Function f) = Function (cvtF f) cvtAT :: Atuple (acc aenv) s -> Atuple (acc aenv) s cvtAT NilAtup = NilAtup
Data/Array/Accelerate/Trafo/Sharing.hs view
@@ -56,7 +56,7 @@ import Data.Array.Accelerate.Array.Sugar as Sugar import Data.Array.Accelerate.AST hiding ( PreOpenAcc(..), OpenAcc(..), Acc , PreOpenExp(..), OpenExp, PreExp, Exp- , Stencil(..)+ , PreBoundary(..), Boundary, Stencil(..) , showPreAccOp, showPreExpOp ) import qualified Data.Array.Accelerate.AST as AST import qualified Data.Array.Accelerate.Debug as Debug@@ -301,13 +301,13 @@ Backpermute newDim perm acc -> AST.Backpermute (cvtE newDim) (cvtF1 perm) (cvtA acc) Stencil stencil boundary acc -> AST.Stencil (convertSharingStencilFun1 config acc alyt aenv' stencil)- (convertBoundary boundary)+ (convertSharingBoundary config alyt aenv' boundary) (cvtA acc) Stencil2 stencil bndy1 acc1 bndy2 acc2 -> AST.Stencil2 (convertSharingStencilFun2 config acc1 acc2 alyt aenv' stencil)- (convertBoundary bndy1)+ (convertSharingBoundary config alyt aenv' bndy1) (cvtA acc1)- (convertBoundary bndy2)+ (convertSharingBoundary config alyt aenv' bndy2) (cvtA acc2) -- Collect seq -> AST.Collect (convertSharingSeq config alyt EmptyLayout aenv' [] seq) @@ -517,11 +517,23 @@ -- | Convert a boundary condition ---convertBoundary :: Elt e => Boundary e -> Boundary (EltRepr e)-convertBoundary Clamp = Clamp-convertBoundary Mirror = Mirror-convertBoundary Wrap = Wrap-convertBoundary (Constant e) = Constant (fromElt e)+convertSharingBoundary+ :: forall aenv t.+ Config+ -> Layout aenv aenv+ -> [StableSharingAcc]+ -> PreBoundary ScopedAcc ScopedExp t+ -> AST.PreBoundary AST.OpenAcc aenv t+convertSharingBoundary config alyt aenv = cvt+ where+ cvt :: PreBoundary ScopedAcc ScopedExp t -> AST.Boundary aenv t+ cvt bndy =+ case bndy of+ Clamp -> AST.Clamp+ Mirror -> AST.Mirror+ Wrap -> AST.Wrap+ Constant v -> AST.Constant $ fromElt v+ Function f -> AST.Function $ convertSharingFun1 config alyt aenv f -- Smart constructors to represent AST forms@@ -1237,6 +1249,20 @@ traverseExp :: Typeable e => Level -> Exp e -> IO (RootExp e, Int) traverseExp = makeOccMapExp config accOccMap + traverseBoundary+ :: Level+ -> PreBoundary Acc Exp t+ -> IO (PreBoundary UnscopedAcc RootExp t, Int)+ traverseBoundary lvl bndy =+ case bndy of+ Clamp -> return (Clamp, 0)+ Mirror -> return (Mirror, 0)+ Wrap -> return (Wrap, 0)+ Constant v -> return (Constant v, 0)+ Function f -> do+ (f', h) <- traverseFun1 lvl f+ return (Function f', h)+ -- traverseSeq :: forall arrs. Typeable arrs -- => Level -> Seq arrs -- -> IO (RootSeq arrs, Int)@@ -1346,15 +1372,18 @@ return (Backpermute e' p' acc', h1 `max` h2 `max` h3 + 1) Stencil s bnd acc -> reconstruct $ do (s' , h1) <- makeOccMapStencil1 config accOccMap acc lvl s- (acc', h2) <- traverseAcc lvl acc- return (Stencil s' bnd acc', h1 `max` h2 + 1)+ (bnd', h2) <- traverseBoundary lvl bnd+ (acc', h3) <- traverseAcc lvl acc+ return (Stencil s' bnd' acc', h1 `max` h2 `max` h3 + 1) Stencil2 s bnd1 acc1 bnd2 acc2 -> reconstruct $ do (s' , h1) <- makeOccMapStencil2 config accOccMap acc1 acc2 lvl s- (acc1', h2) <- traverseAcc lvl acc1- (acc2', h3) <- traverseAcc lvl acc2- return (Stencil2 s' bnd1 acc1' bnd2 acc2',- h1 `max` h2 `max` h3 + 1)+ (bnd1', h2) <- traverseBoundary lvl bnd1+ (acc1', h3) <- traverseAcc lvl acc1+ (bnd2', h4) <- traverseBoundary lvl bnd2+ (acc2', h5) <- traverseAcc lvl acc2+ return (Stencil2 s' bnd1' acc1' bnd2' acc2',+ h1 `max` h2 `max` h3 `max` h4 `max` h5 + 1) -- Collect s -> reconstruct $ do -- (s', h) <- traverseSeq lvl s -- return (Collect s', h + 1)@@ -2185,17 +2214,20 @@ (accCount1 +++ accCount2 +++ accCount3) Stencil st bnd acc -> let (st' , accCount1) = scopesStencil1 acc st- (acc', accCount2) = scopesAcc acc+ (bnd', accCount2) = scopesBoundary bnd+ (acc', accCount3) = scopesAcc acc in- reconstruct (Stencil st' bnd acc') (accCount1 +++ accCount2)+ reconstruct (Stencil st' bnd' acc') (accCount1 +++ accCount2 +++ accCount3) Stencil2 st bnd1 acc1 bnd2 acc2 -> let (st' , accCount1) = scopesStencil2 acc1 acc2 st- (acc1', accCount2) = scopesAcc acc1- (acc2', accCount3) = scopesAcc acc2+ (bnd1', accCount2) = scopesBoundary bnd1+ (acc1', accCount3) = scopesAcc acc1+ (bnd2', accCount4) = scopesBoundary bnd2+ (acc2', accCount5) = scopesAcc acc2 in- reconstruct (Stencil2 st' bnd1 acc1' bnd2 acc2')- (accCount1 +++ accCount2 +++ accCount3)+ reconstruct (Stencil2 st' bnd1' acc1' bnd2' acc2')+ (accCount1 +++ accCount2 +++ accCount3 +++ accCount4 +++ accCount5) -- Collect seq -> let -- (seq', accCount1) = scopesSeq seq -- in@@ -2406,7 +2438,18 @@ where (body, counts) = scopesExp (stencilFun undefined undefined) + scopesBoundary :: PreBoundary UnscopedAcc RootExp t+ -> (PreBoundary ScopedAcc ScopedExp t, NodeCounts)+ scopesBoundary bndy =+ case bndy of+ Clamp -> (Clamp, noNodeCounts)+ Mirror -> (Mirror, noNodeCounts)+ Wrap -> (Wrap, noNodeCounts)+ Constant v -> (Constant v, noNodeCounts)+ Function f -> let (body, counts) = scopesFun1 f+ in (Function body, counts) + determineScopesExp :: Config -> OccMap Acc@@ -2794,6 +2837,7 @@ -- environment for de Bruijn conversion will have a duplicate entry, and hence, be of the wrong -- size, which is fatal. (The 'buildInitialEnv*' functions will already bail out.) --+{-# NOINLINE recoverSharingAcc #-} recoverSharingAcc :: Typeable a => Config@@ -2801,7 +2845,6 @@ -> [Level] -- The tags of newly introduced free array variables -> Acc a -> (ScopedAcc a, [StableSharingAcc])-{-# NOINLINE recoverSharingAcc #-} recoverSharingAcc config alvl avars acc = let (acc', occMap) = unsafePerformIO -- to enable stable pointers; this is safe as explained above@@ -2810,6 +2853,7 @@ determineScopesAcc config avars occMap acc' +{-# NOINLINE recoverSharingExp #-} recoverSharingExp :: Typeable e => Config@@ -2817,7 +2861,6 @@ -> [Level] -- The tags of newly introduced free scalar variables -> Exp e -> (ScopedExp e, [StableSharingExp])-{-# NOINLINE recoverSharingExp #-} recoverSharingExp config lvl fvar exp = let (rootExp, accOccMap) = unsafePerformIO $ do@@ -2834,12 +2877,12 @@ {--+{-# NOINLINE recoverSharingSeq #-} recoverSharingSeq :: Typeable e => Config -> Seq e -> (ScopedSeq e, [StableSharingSeq])-{-# NOINLINE recoverSharingSeq #-} recoverSharingSeq config seq = let (rootSeq, accOccMap) = unsafePerformIO $ do
Data/Array/Accelerate/Trafo/Simplify.hs view
@@ -37,6 +37,7 @@ -- friends import Data.Array.Accelerate.AST hiding ( prj )+import Data.Array.Accelerate.Analysis.Match import Data.Array.Accelerate.Analysis.Shape import Data.Array.Accelerate.Error import Data.Array.Accelerate.Product@@ -45,7 +46,7 @@ import Data.Array.Accelerate.Trafo.Shrink import Data.Array.Accelerate.Trafo.Substitution import Data.Array.Accelerate.Type-import Data.Array.Accelerate.Array.Sugar ( Elt, Shape, Slice, toElt, fromElt, (:.)(..)+import Data.Array.Accelerate.Array.Sugar ( Array, Elt(eltType), Shape, Slice, toElt, fromElt, Z(..), (:.)(..) , Tuple(..), IsTuple, fromTuple, TupleRepr, shapeToList ) import qualified Data.Array.Accelerate.Debug as Stats @@ -237,7 +238,7 @@ (v, fx) = evalPrimApp env f x' Index a sh -> Index a <$> cvtE sh LinearIndex a i -> LinearIndex a <$> cvtE i- Shape a -> pure $ Shape a+ Shape a -> shape a ShapeSize sh -> shapeSize (cvtE sh) Intersect s t -> cvtE s `intersect` cvtE t Union s t -> cvtE s `union` cvtE t@@ -391,6 +392,13 @@ indexTail (_, IndexCons sl _) = Stats.ruleFired "indexTail/indexCons" $ yes sl indexTail sh = IndexTail <$> sh + shape :: forall sh t. (Shape sh, Elt t) => acc aenv (Array sh t) -> (Any, PreOpenExp acc env aenv sh)+ shape _+ | Just Refl <- matchTupleType (eltType (undefined::sh)) (eltType (undefined::Z))+ = Stats.ruleFired "shape/Z" $ yes (Const (fromElt Z))+ shape a+ = pure $ Shape a+ shapeSize :: forall sh. Shape sh => (Any, PreOpenExp acc env aenv sh) -> (Any, PreOpenExp acc env aenv Int) shapeSize (_, Const c) = Stats.ruleFired "shapeSize/const" $ yes (Const (product (shapeToList (toElt c :: sh)))) shapeSize sh = ShapeSize <$> sh@@ -671,6 +679,7 @@ PrimFloor f i -> travFloatingType f +++ travIntegralType i PrimCeiling f i -> travFloatingType f +++ travIntegralType i PrimIsNaN t -> travFloatingType t+ PrimIsInfinite t -> travFloatingType t PrimAtan2 t -> travFloatingType t PrimLt t -> travScalarType t PrimGt t -> travScalarType t
Data/Array/Accelerate/Trafo/Substitution.hs view
@@ -260,6 +260,16 @@ {-# INLINEABLE weaken #-} weaken k = Stats.substitution "weaken" . rebuildA (Avar . k) +instance RebuildableAcc acc => Sink (PreBoundary acc) where+ {-# INLINEABLE weaken #-}+ weaken k bndy =+ case bndy of+ Clamp -> Clamp+ Mirror -> Mirror+ Wrap -> Wrap+ Constant c -> Constant c+ Function f -> Function (weaken k f)+ instance Sink OpenAcc where {-# INLINEABLE weaken #-} weaken k = Stats.substitution "weaken" . rebuildA (Avar . k)@@ -495,8 +505,8 @@ Scanr1 f a -> Scanr1 <$> rebuildFun k (pure . IE) av f <*> k av a Permute f1 a1 f2 a2 -> Permute <$> rebuildFun k (pure . IE) av f1 <*> k av a1 <*> rebuildFun k (pure . IE) av f2 <*> k av a2 Backpermute sh f a -> Backpermute <$> rebuildPreOpenExp k (pure . IE) av sh <*> rebuildFun k (pure . IE) av f <*> k av a- Stencil f b a -> Stencil <$> rebuildFun k (pure . IE) av f <*> pure b <*> k av a- Stencil2 f b1 a1 b2 a2 -> Stencil2 <$> rebuildFun k (pure . IE) av f <*> pure b1 <*> k av a1 <*> pure b2 <*> k av a2+ Stencil f b a -> Stencil <$> rebuildFun k (pure . IE) av f <*> rebuildBoundary k av b <*> k av a+ Stencil2 f b1 a1 b2 a2 -> Stencil2 <$> rebuildFun k (pure . IE) av f <*> rebuildBoundary k av b1 <*> k av a1 <*> rebuildBoundary k av b2 <*> k av a2 -- Collect seq -> Collect <$> rebuildSeq k av seq Aforeign ff afun as -> Aforeign ff afun <$> k av as @@ -523,6 +533,21 @@ case atup of NilAtup -> pure NilAtup SnocAtup t a -> SnocAtup <$> rebuildAtup k av t <*> k av a++{-# INLINEABLE rebuildBoundary #-}+rebuildBoundary+ :: (Applicative f, SyntacticAcc fa)+ => RebuildAcc acc+ -> (forall t'. Arrays t' => Idx aenv t' -> f (fa acc aenv' t'))+ -> PreBoundary acc aenv t+ -> f (PreBoundary acc aenv' t)+rebuildBoundary k av bndy =+ case bndy of+ Clamp -> pure Clamp+ Mirror -> pure Mirror+ Wrap -> pure Wrap+ Constant v -> pure (Constant v)+ Function f -> Function <$> rebuildFun k (pure . IE) av f {-- {-# INLINEABLE rebuildSeq #-}
Data/Array/Accelerate/Type.hs view
@@ -3,7 +3,6 @@ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-}-{-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-}@@ -83,6 +82,7 @@ CLLong, CULLong, CFloat, CDouble) -- in the future, CHalf + -- Scalar types -- ------------ @@ -104,6 +104,7 @@ NonNumDict :: ( Bounded a, Enum a, Eq a, Ord a, Show a, Storable a ) => NonNumDict a + -- Scalar type representation -- @@ -212,10 +213,6 @@ show (NumScalarType ty) = show ty show (NonNumScalarType ty) = show ty -instance Show (TupleType a) where- show UnitTuple = "()"- show (SingleTuple scalarTy) = show scalarTy- show (PairTuple a b) = "("++show a++", "++show b++")" -- Querying scalar type representations --@@ -592,7 +589,12 @@ SingleTuple :: ScalarType a -> TupleType a PairTuple :: TupleType a -> TupleType b -> TupleType (a, b) +instance Show (TupleType a) where+ show UnitTuple = "()"+ show (SingleTuple scalarTy) = show scalarTy+ show (PairTuple a b) = "("++show a++", "++show b++")" + -- Type-level bit sizes -- -------------------- @@ -643,23 +645,11 @@ 64 -> [t| 64 |] _ -> error "I don't know what architecture I am" ) - type instance BitSize CULong = $( case finiteBitSize (undefined::CULong) of 32 -> [t| 32 |] 64 -> [t| 64 |] _ -> error "I don't know what architecture I am" ) ---- Stencil support--- ------------------- |Boundary condition specification for stencil operations.----data Boundary a = Clamp -- ^clamp coordinates to the extent of the array- | Mirror -- ^mirror coordinates beyond the array extent- | Wrap -- ^wrap coordinates around on each dimension- | Constant a -- ^use a constant value for outlying coordinates- deriving (Show, Read) {- -- Vector GPU data types
+ README.md view
@@ -0,0 +1,240 @@+An Embedded Language for Accelerated Array Computations+=======================================================++[](https://travis-ci.org/AccelerateHS/accelerate)+[](https://hackage.haskell.org/package/accelerate)++`Data.Array.Accelerate` defines an embedded language of array computations for high-performance computing in Haskell. Computations on multi-dimensional, regular arrays are expressed in the form of parameterised collective operations (such as maps, reductions, and permutations). These computations are online-compiled and executed on a range of architectures.++For more details, see our papers:++ * [Accelerating Haskell Array Codes with Multicore GPUs][CKLM+11]+ * [Optimising Purely Functional GPU Programs][MCKL13] ([slides][MCKL13-slides])+ * [Embedding Foreign Code][CMCK14]+ * [Type-safe Runtime Code Generation: Accelerate to LLVM][MCGN15] ([slides][MCGN15-slides]) ([video][MCGN15-video])++There are also slides from some fairly recent presentations:++ * [Embedded Languages for High-Performance Computing in Haskell][Embedded]+ * [GPGPU Programming in Haskell with Accelerate][YLJ13-slides] ([video][YLJ13-video]) ([workshop][YLJ13-workshop])++Chapter 6 of Simon Marlow's book [Parallel and Concurrent Programming in Haskell][Mar13] contains a tutorial introduction to Accelerate.++[Trevor's PhD thesis][Trevor-thesis] details the design and implementation of frontend optimisations and CUDA backend.+++**Table of Contents**++- [An Embedded Language for Accelerated Array Computations](#an-embedded-language-for-accelerated-array-computations)+ - [A simple example](#a-simple-example)+ - [Availability](#availability)+ - [Additional components](#additional-components)+ - [Requirements](#requirements)+ - [Documentation](#documentation)+ - [Examples](#examples)+ - [Mailing list and contacts](#mailing-list-and-contacts)+ - [Citing Accelerate](#citing-accelerate)+ - [What's missing?](#whats-missing)++A simple example+----------------++As a simple example, consider the computation of a dot product of two vectors of single-precision floating-point numbers:++ dotp :: Acc (Vector Float) -> Acc (Vector Float) -> Acc (Scalar Float)+ dotp xs ys = fold (+) 0 (zipWith (*) xs ys)++Except for the type, this code is almost the same as the corresponding Haskell code on lists of floats. The types indicate that the computation may be online-compiled for performance; for example, using `Data.Array.Accelerate.LLVM.PTX.run` it may be on-the-fly off-loaded to a GPU.++Availability+------------++Package accelerate is available from++ * Hackage: [accelerate][Hackage] - install with `cabal install accelerate`+ * GitHub: [AccelerateHS/accelerate][GitHub] - get the source with `git clone https://github.com/AccelerateHS/accelerate.git`. The easiest way to compile the source distributions is via the Haskell [stack](https://docs.haskellstack.org/en/stable/README/) tool.++Additional components+---------------------++The following supported add-ons are available as separate packages:++ * [accelerate-llvm-native][accelerate-llvm-native]: Backend targeting multicore CPUs+ * [accelerate-llvm-ptx][accelerate-llvm-ptx]: Backend targeting CUDA-enabled NVIDIA GPUs. Requires a GPU with compute capability 2.0 or greater (see the [table on Wikipedia][wiki-cc])+ * [accelerate-examples][accelerate-examples]: Computational kernels and applications showcasing the use of Accelerate as well as a regression test suite (supporting function and performance testing)+ * [accelerate-io][accelerate-io]: Fast conversion between Accelerate arrays and other array formats (for example, Repa and Vector)+ * [accelerate-fft][accelerate-fft]: Fast Fourier transform implementation, with FFI bindings to optimised implementations+ * [accelerate-blas][accelerate-blas]: BLAS and LAPACK operations, with FFI bindings to optimised implementations+ * [accelerate-bignum][accelerate-bignum]: Fixed-width large integer arithmetic+ * [colour-accelerate][colour-accelerate]: Colour representations in Accelerate (RGB, sRGB, HSV, and HSL)+ * [gloss-accelerate][gloss-accelerate]: Generate [gloss][gloss] pictures from Accelerate+ * [gloss-raster-accelerate][gloss-raster-accelerate]: Parallel rendering of raster images and animations+ * [lens-accelerate][lens-accelerate]: [Lens][lens] operators for Accelerate types+ * [linear-accelerate][linear-accelerate]: [Linear][linear] vector spaces in Accelerate+ * [mwc-random-accelerate][mwc-random-accelerate]: Generate Accelerate arrays filled with high quality pseudorandom numbers+ * [numeric-prelude-accelerate][numeric-prelude-accelerate]: Lifting the [numeric-prelude][numeric-prelude] to Accelerate++Install them from Hackage with `cabal install PACKAGENAME`.+++Documentation+-------------++ * Haddock documentation is included and linked with the individual package releases on [Hackage][Hackage].+ * Haddock documentation for in-development components can be found [here](http://tmcdonell-bot.github.io/accelerate-travis-buildbot/).+ * The idea behind the HOAS (higher-order abstract syntax) to de-Bruijn conversion used in the library is [described separately][HOAS-conv].++Examples+--------++### accelerate-examples++The [accelerate-examples][accelerate-examples] package provides a range of computational kernels and a few complete applications. To install these from Hackage, issue `cabal install accelerate-examples`. The examples include:++ * An implementation of [canny edge detection][wiki-canny]+ * An interactive [mandelbrot set][wiki-mandelbrot] generator+ * An [N-body simulation][wiki-nbody] of gravitational attraction between solid particles+ * An implementation of the [PageRank][wiki-pagerank] algorithm+ * A simple [ray-tracer][wiki-raytracing]+ * A particle based simulation of stable fluid flows+ * A cellular automata simulation+ * A "password recovery" tool, for dictionary lookup of MD5 hashes++[](http://i.imgur.com/RgXRqsc.jpg)+[](http://i.imgur.com/ZNEGEJK.jpg)++<!--+<video width=400 height=300 controls=false autoplay loop>+ <source="http://www.cse.unsw.edu.au/~tmcdonell/images/ray.mp4" type="video/mp4">+</video>+-->+++### LULESH++[LULESH-accelerate][lulesh-accelerate] is in implementation of the Livermore Unstructured Lagrangian Explicit Shock Hydrodynamics (LULESH) mini-app. [LULESH][LULESH] represents a typical hydrodynamics code such as [ALE3D][ALE3D], but is a highly simplified application, hard-coded to solve the Sedov blast problem on an unstructured hexahedron mesh.+++++### Λ ○ λ (Lol)++Λ ○ λ ([Lol][lol]) is a general-purpose library for ring-based lattice cryptography. Lol has applications in, for example, symmetric-key somewhat-homomorphic encryption schemes. The [lol-accelerate][lol-accelerate] package provides an Accelerate backend for Lol.+++### Additional examples++Accelerate users have also built some substantial applications of their own.+Please feel free to add your own examples!++ * Henning Thielemann, [patch-image](http://hackage.haskell.org/package/patch-image): Combine a collage of overlapping images+ * apunktbau, [bildpunkt](https://github.com/abau/bildpunkt): A ray-marching distance field renderer+ * klarh, [hasdy](https://github.com/klarh/hasdy): Molecular dynamics in Haskell using Accelerate+ * Alexandros Gremm used Accelerate as part of the [2014 CSCS summer school](http://user.cscs.ch/blog/2014/cscs_usi_summer_school_2014_30_june_10_july_2014_in_serpiano_tessin/index.html) ([code](https://github.com/agremm/cscs))+++Mailing list and contacts+-------------------------++ * Mailing list: [`accelerate-haskell@googlegroups.com`](mailto:accelerate-haskell@googlegroups.com) (discussions on both use and development are welcome)+ * Sign up for the mailing list at the [Accelerate Google Groups page][Google-Group].+ * Bug reports and issues tracking: [GitHub project page][Issues].++The maintainers of Accelerate are Manuel M T Chakravarty <chak@cse.unsw.edu.au> and Trevor L McDonell <tmcdonell@cse.unsw.edu.au>.+++Citing Accelerate+-----------------++If you use Accelerate for academic research, you are encouraged (though not+required) to cite the following papers ([BibTeX](http://www.cse.unsw.edu.au/~tmcdonell/papers/accelerate.bib)):++ * Manuel M. T. Chakravarty, Gabriele Keller, Sean Lee, Trevor L. McDonell, and Vinod Grover.+ [Accelerating Haskell Array Codes with Multicore GPUs][CKLM+11].+ In _DAMP '11: Declarative Aspects of Multicore Programming_, ACM, 2011.++ * Trevor L. McDonell, Manuel M. T. Chakravarty, Gabriele Keller, and Ben Lippmeier.+ [Optimising Purely Functional GPU Programs][MCKL13].+ In _ICFP '13: The 18th ACM SIGPLAN International Conference on Functional Programming_, ACM, 2013.++ * Robert Clifton-Everest, Trevor L. McDonell, Manuel M. T. Chakravarty, and Gabriele Keller.+ [Embedding Foreign Code][CMCK14].+ In _PADL '14: The 16th International Symposium on Practical Aspects of Declarative Languages_, Springer-Verlag, LNCS, 2014.++ * Trevor L. McDonell, Manuel M. T. Chakravarty, Vinod Grover, and Ryan R. Newton.+ [Type-safe Runtime Code Generation: Accelerate to LLVM][MCGN15].+ In _Haskell '15: The 8th ACM SIGPLAN Symposium on Haskell_, ACM, 2015.++Accelerate is primarily developed by academics, so citations matter a lot to us.+As an added benefit, you increase Accelerate's exposure and potential user (and+developer!) base, which is a benefit to all users of Accelerate. Thanks in advance!+++What's missing?+---------------++Here is a list of features that are currently missing:++ * Preliminary API (parts of the API may still change in subsequent releases)++++ [CKLM+11]: http://www.cse.unsw.edu.au/~chak/papers/CKLM+11.html+ [MCKL13]: http://www.cse.unsw.edu.au/~chak/papers/MCKL13.html+ [MCKL13-slides]: https://speakerdeck.com/tmcdonell/optimising-purely-functional-gpu-programs+ [CMCK14]: http://www.cse.unsw.edu.au/~chak/papers/CMCK14.html+ [MCGN15]: http://www.cse.unsw.edu.au/~chak/papers/MCGN15.html+ [MCGN15-slides]: https://speakerdeck.com/tmcdonell/type-safe-runtime-code-generation-accelerate-to-llvm+ [MCGN15-video]: https://www.youtube.com/watch?v=snXhXA5noVc+ [HIW'09]: https://wiki.haskell.org/HaskellImplementorsWorkshop+ [Mar13]: http://chimera.labs.oreilly.com/books/1230000000929+ [Embedded]: https://speakerdeck.com/mchakravarty/embedded-languages-for-high-performance-computing-in-haskell+ [Hackage]: http://hackage.haskell.org/package/accelerate+ [accelerate-cuda]: https://github.com/AccelerateHS/accelerate-cuda+ [accelerate-examples]: https://github.com/AccelerateHS/accelerate-examples+ [accelerate-io]: https://github.com/AccelerateHS/accelerate-io+ [accelerate-fft]: https://github.com/AccelerateHS/accelerate-fft+ [accelerate-blas]: https://github.com/tmcdonell/accelerate-blas+ [accelerate-backend-kit]: https://github.com/AccelerateHS/accelerate-backend-kit+ [accelerate-buildbot]: https://github.com/AccelerateHS/accelerate-buildbot+ [accelerate-repa]: https://github.com/blambo/accelerate-repa+ [accelerate-opencl]: https://github.com/hiPERFIT/accelerate-opencl+ [accelerate-cabal]: https://github.com/AccelerateHS/accelerate/accelerate.cabal+ [accelerate-cuda-cabal]: https://github.com/AccelerateHS/accelerate-cuda/accelerate-cuda.cabal+ [accelerate-llvm]: https://github.com/AccelerateHS/accelerate-llvm+ [accelerate-llvm-native]: https://github.com/AccelerateHS/accelerate-llvm+ [accelerate-llvm-ptx]: https://github.com/AccelerateHS/accelerate-llvm+ [accelerate-bignum]: https://github.com/tmcdonell/accelerate-bignum+ [GitHub]: https://github.com/AccelerateHS/accelerate+ [Wiki]: https://github.com/AccelerateHS/accelerate/wiki+ [Issues]: https://github.com/AccelerateHS/accelerate/issues+ [Google-Group]: http://groups.google.com/group/accelerate-haskell+ [HOAS-conv]: http://www.cse.unsw.edu.au/~chak/haskell/term-conv/+ [repa]: http://hackage.haskell.org/package/repa+ [wiki-cc]: https://en.wikipedia.org/wiki/CUDA#Supported_GPUs+ [YLJ13-video]: http://youtu.be/ARqE4yT2Z0o+ [YLJ13-slides]: https://speakerdeck.com/tmcdonell/gpgpu-programming-in-haskell-with-accelerate+ [YLJ13-workshop]: https://speakerdeck.com/tmcdonell/gpgpu-programming-in-haskell-with-accelerate-workshop+ [wiki-canny]: https://en.wikipedia.org/wiki/Canny_edge_detector+ [wiki-mandelbrot]: https://en.wikipedia.org/wiki/Mandelbrot_set+ [wiki-nbody]: https://en.wikipedia.org/wiki/N-body+ [wiki-raytracing]: https://en.wikipedia.org/wiki/Ray_tracing+ [wiki-pagerank]: https://en.wikipedia.org/wiki/Pagerank+ [Trevor-thesis]: http://www.cse.unsw.edu.au/~tmcdonell/papers/TrevorMcDonell_PhD_submission.pdf+ [colour-accelerate]: https://github.com/tmcdonell/colour-accelerate+ [gloss]: https://hackage.haskell.org/package/gloss+ [gloss-accelerate]: https://github.com/tmcdonell/gloss-accelerate+ [gloss-raster-accelerate]: https://github.com/tmcdonell/gloss-raster-accelerate+ [lens]: https://hackage.haskell.org/package/lens+ [lens-accelerate]: https://github.com/tmcdonell/lens-accelerate+ [linear]: https://hackage.haskell.org/package/linear+ [linear-accelerate]: https://github.com/tmcdonell/linear-accelerate+ [mwc-random-accelerate]: https://github.com/tmcdonell/mwc-random-accelerate+ [numeric-prelude]: https://hackage.haskell.org/package/numeric-prelude+ [numeric-prelude-accelerate]: https://github.com/tmcdonell/numeric-prelude-accelerate+ [LULESH]: https://codesign.llnl.gov/lulesh.php+ [ALE3D]: https://wci.llnl.gov/simulation/computer-codes/ale3d+ [lulesh-accelerate]: https://github.com/tmcdonell/lulesh-accelerate+ [lol]: https://hackage.haskell.org/package/lol+ [lol-accelerate]: https://github.com/tmcdonell/lol-accelerate+
accelerate.cabal view
@@ -1,5 +1,5 @@ Name: accelerate-Version: 1.0.0.0+Version: 1.1.0.0 Cabal-version: >= 1.8 Tested-with: GHC >= 7.8 Build-type: Simple@@ -39,10 +39,6 @@ greater. See the following table for supported GPUs: <http://en.wikipedia.org/wiki/CUDA#Supported_GPUs> .- * @accelerate-cuda@: Backend targeting CUDA-enabled NVIDIA GPUs. Requires- a GPU with compute compatibility 1.2 or greater. /NOTE: This backend is- being deprecated in favour of @accelerate-llvm-ptx@./- . * @accelerate-examples@: Computational kernels and applications showcasing the use of Accelerate as well as a regression test suite, supporting function and performance testing.@@ -129,7 +125,9 @@ Category: Compilers/Interpreters, Concurrency, Data, Parallelism Stability: Experimental -Extra-source-files: changelog.md+Extra-source-files:+ README.md+ CHANGELOG.md Flag debug Default: False@@ -154,6 +152,8 @@ . * @flush-cache@: Clear any persistent caches on program startup (False). .+ * @force-recomp@: Force recompilation of array programs (False).+ . * @fast-math@: Allow algebraically equivalent transformations which may change floating point results (e.g., reassociate) (True). .@@ -206,8 +206,13 @@ Description: Enable hooks for monitoring the running application using EKG. Implies @debug@ mode. In order to view the metrics, your application will need to- initialise the EKG server like so:+ call @Data.Array.Accelerate.Debug.beginMonitoring@ before running any+ Accelerate computations. This will launch the server on the local machine at+ port 8000. .+ Alternatively, if you wish to configure the EKG monitoring server you can+ initialise it like so:+ . > import Data.Array.Accelerate.Debug > > import System.Metrics@@ -223,7 +228,7 @@ > ... . Note that, as with any program utilising EKG, in order to collect Haskell GC- statistics collection, you must either run the program with:+ statistics, you must either run the program with: . > +RTS -T -RTS .@@ -246,7 +251,7 @@ Library Build-depends:- base >= 4.7 && < 4.10+ base >= 4.7 && < 4.11 , base-orphans >= 0.3 , containers >= 0.3 , deepseq >= 1.3@@ -278,6 +283,7 @@ -- For backend development Data.Array.Accelerate.AST+ Data.Array.Accelerate.Analysis.Hash Data.Array.Accelerate.Analysis.Match Data.Array.Accelerate.Analysis.Shape Data.Array.Accelerate.Analysis.Stencil@@ -303,6 +309,7 @@ Other-modules: Data.Atomic+ Data.Array.Accelerate.Analysis.Hash.TH Data.Array.Accelerate.Array.Lifted Data.Array.Accelerate.Array.Remote.Nursery Data.Array.Accelerate.Classes@@ -383,6 +390,10 @@ if impl(ghc >= 8.0) ghc-options: -freduction-depth=35 + if impl(ghc < 7.10)+ build-depends:+ th-lift-instances >= 0.1+ -- Don't add the extensions list here. Instead, place individual LANGUAGE -- pragmas in the files that require a specific extension. This means the -- project loads in GHCi, and avoids extension clashes.@@ -395,7 +406,7 @@ source-repository this Type: git- Tag: 1.0.0.0+ Tag: 1.1.0.0 Location: git://github.com/AccelerateHS/accelerate.git -- vim: nospell
− changelog.md
@@ -1,90 +0,0 @@-1.0.0.0-- * Many API and internal changes-- * Bug fixes and other enhancements--0.15.0.0-- * Bug fixes and performance improvements.--0.14.0.0-- * New iteration constructs.-- * Additional Prelude-like functions.-- * Improved code generation and fusion optimisation.-- * Concurrent kernel execution in the CUDA backend.-- * Bug fixes.--0.13.0.0-- * New array fusion optimisation.-- * New foreign function interface for array and scalar expressions.-- * Additional Prelude-like functions.-- * New example programs.-- * Bug fixes and performance improvements.--0.12.0.0-- * Full sharing recovery in scalar expressions and array computations.-- * Two new example applications in package `accelerate-examples`: Real-time- Canny edge detection and an interactive fluid flow simulator (both including- a graphical frontend).-- * Bug fixes.--0.11.0.0-- * New Prelude-like functions `zip*`, `unzip*`, `fill`, `enumFrom*`, `tail`,- `init`, `drop`, `take`, `slit`, `gather*`, `scatter*`, and `shapeSize`.-- * New simplified AST (in package `accelerate-backend-kit`) for backend writers- who want to avoid the complexities of the type-safe AST.--0.10.0.0-- * Complete sharing recovery for scalar expressions (but currently disabled by- default).-- * Also bug fixes in array sharing recovery and a few new convenience- functions.--0.9.0.0-- * Streaming computations-- * Precompilation-- * Repa-style array indices-- * Additional collective operations supported by the CUDA backend: `stencil`s,- more `scan`s, rank-polymorphic `fold`, `generate`.-- * Conversions to other array formats-- * Bug fixes--0.8.1.0-- * Bug fixes and some performance tweaks.--0.8.0.0-- * More collective operations supported by the CUDA backend: `replicate`,- `slice` and `foldSeg`. Frontend and interpreter support for `stencil`.-- * Bug fixes.--0.7.1.0-- * Initial release of the CUDA backend-