knead 0.2.3 → 0.3
raw patch · 24 files changed
+1903/−1320 lines, 24 filesdep +bool8dep ~llvm-extradep ~llvm-tf
Dependencies added: bool8
Dependency ranges changed: llvm-extra, llvm-tf
Files
- knead.cabal +14/−10
- src/Data/Array/Knead/Code.hs +1/−1
- src/Data/Array/Knead/Expression.hs +35/−23
- src/Data/Array/Knead/Expression/Vector.hs +110/−0
- src/Data/Array/Knead/Index/Linear.hs +0/−558
- src/Data/Array/Knead/Index/Linear/Int.hs +0/−59
- src/Data/Array/Knead/Index/Nested/Shape.hs +0/−505
- src/Data/Array/Knead/Parameter.hs +3/−0
- src/Data/Array/Knead/Parameterized/Physical.hs +9/−9
- src/Data/Array/Knead/Parameterized/PhysicalHull.hs +262/−18
- src/Data/Array/Knead/Parameterized/Private.hs +4/−2
- src/Data/Array/Knead/Parameterized/Render.hs +58/−5
- src/Data/Array/Knead/Parameterized/Slice.hs +3/−3
- src/Data/Array/Knead/Parameterized/Symbolic.hs +1/−1
- src/Data/Array/Knead/Shape/Cubic.hs +581/−0
- src/Data/Array/Knead/Shape/Cubic/Int.hs +59/−0
- src/Data/Array/Knead/Shape/Nested.hs +539/−0
- src/Data/Array/Knead/Simple/Fold.hs +5/−6
- src/Data/Array/Knead/Simple/Physical.hs +8/−16
- src/Data/Array/Knead/Simple/PhysicalPrivate.hs +171/−44
- src/Data/Array/Knead/Simple/Private.hs +24/−36
- src/Data/Array/Knead/Simple/ShapeDependent.hs +3/−4
- src/Data/Array/Knead/Simple/Slice.hs +3/−3
- src/Data/Array/Knead/Simple/Symbolic.hs +10/−17
knead.cabal view
@@ -1,12 +1,12 @@ Name: knead-Version: 0.2.3+Version: 0.3 License: BSD3 License-File: LICENSE Author: Henning Thielemann <haskell@henning-thielemann.de> Maintainer: Henning Thielemann <haskell@henning-thielemann.de> Homepage: http://hub.darcs.net/thielema/knead/ Category: Data Structures-Synopsis: Repa array processing using LLVM JIT+Synopsis: Repa-like array processing using LLVM JIT Description: This library processes arrays like @Repa@ and @Accelerate@, but it uses the just-in-time compiler of @LLVM@@@ -15,7 +15,8 @@ that can be run without a GPU. You do not need to care about inlining and strictness annotations, because the LLVM code is by default inlined and strict.- The package is the basis for an LLVM backend for the @Accelerate@ framework.+ The package is intended as the basis+ for an LLVM backend for the @Accelerate@ framework. . Highlights: .@@ -42,12 +43,13 @@ . The name of the package is inspired by the visualization of typical operations like reshaping, collapsing a dimension and extruding another one.-Tested-With: GHC==7.4.2, GHC==7.8.4, GHC==8.0.1+Tested-With: GHC==7.4.2, GHC==7.8.4+Tested-With: GHC==8.4.3, GHC==8.6.1 Cabal-Version: >=1.6 Build-Type: Simple Source-Repository this- Tag: 0.2.3+ Tag: 0.3 Type: darcs Location: http://hub.darcs.net/thielema/knead/ @@ -57,11 +59,12 @@ Library Build-Depends:- llvm-extra >=0.7.3 && <0.8,- llvm-tf >=3.1 && <3.2,+ llvm-extra >=0.8 && <0.9,+ llvm-tf >=3.1.1 && <3.2, tfp >=1.0 && <1.1, storable-tuple >=0.0 && <0.1, storable-record >=0.0.3 && <0.1,+ bool8 >=0.0 && <0.1, transformers >=0.3 && <0.6, utility-ht >=0.0.1 && <0.1, base >=4 && <5@@ -69,10 +72,11 @@ GHC-Options: -Wall Hs-Source-Dirs: src Exposed-Modules:- Data.Array.Knead.Index.Linear.Int- Data.Array.Knead.Index.Linear- Data.Array.Knead.Index.Nested.Shape+ Data.Array.Knead.Shape.Nested+ Data.Array.Knead.Shape.Cubic+ Data.Array.Knead.Shape.Cubic.Int Data.Array.Knead.Expression+ Data.Array.Knead.Expression.Vector Data.Array.Knead.Parameter Data.Array.Knead.Simple.Symbolic Data.Array.Knead.Simple.ShapeDependent
src/Data/Array/Knead/Code.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE TypeFamilies #-} module Data.Array.Knead.Code where -import qualified Data.Array.Knead.Index.Nested.Shape as Shape+import qualified Data.Array.Knead.Shape.Nested as Shape import qualified LLVM.Extra.Multi.Value as MultiValue
src/Data/Array/Knead/Expression.hs view
@@ -5,15 +5,15 @@ import qualified LLVM.Extra.Multi.Value as MultiValue import qualified LLVM.Extra.Arithmetic as A import qualified LLVM.Extra.Control as C-import qualified LLVM.Extra.Monad as LMonad import qualified LLVM.Core as LLVM-import LLVM.Extra.Multi.Value (PatternTuple, Decomposed, Atom, atom, )+import LLVM.Extra.Multi.Value (PatternTuple, Decomposed, Atom, ) -import qualified Control.Monad as Monad+import qualified Control.Monad.HT as Monad import qualified Data.Tuple.HT as TupleHT import qualified Data.Tuple as Tuple import Data.Complex (Complex((:+)))+import Data.Bool8 (Bool8) import Prelude hiding (fst, snd, min, max, zip, unzip, zip3, unzip3,@@ -47,10 +47,10 @@ instance Value Exp where lift0 a = Exp (return a)- lift1 f (Exp a) = Exp (Monad.liftM f a)- lift2 f (Exp a) (Exp b) = Exp (Monad.liftM2 f a b)- lift3 f (Exp a) (Exp b) (Exp c) = Exp (Monad.liftM3 f a b c)- lift4 f (Exp a) (Exp b) (Exp c) (Exp d) = Exp (Monad.liftM4 f a b c d)+ lift1 f (Exp a) = Exp (Monad.lift f a)+ lift2 f (Exp a) (Exp b) = Exp (Monad.lift2 f a b)+ lift3 f (Exp a) (Exp b) (Exp c) = Exp (Monad.lift3 f a b c)+ lift4 f (Exp a) (Exp b) (Exp c) (Exp d) = Exp (Monad.lift4 f a b c d) liftM ::@@ -65,14 +65,14 @@ MultiValue.T a -> MultiValue.T b -> LLVM.CodeGenFunction r (MultiValue.T c)) -> (Exp a -> Exp b -> Exp c)-liftM2 f (Exp a) (Exp b) = Exp (LMonad.liftR2 f a b)+liftM2 f (Exp a) (Exp b) = Exp (Monad.liftJoin2 f a b) liftM3 :: (forall r. MultiValue.T a -> MultiValue.T b -> MultiValue.T c -> LLVM.CodeGenFunction r (MultiValue.T d)) -> (Exp a -> Exp b -> Exp c -> Exp d)-liftM3 f (Exp a) (Exp b) (Exp c) = Exp (LMonad.liftR3 f a b c)+liftM3 f (Exp a) (Exp b) (Exp c) = Exp (Monad.liftJoin3 f a b c) unliftM1 ::@@ -94,13 +94,6 @@ -min :: (MultiValue.Real a) => Exp a -> Exp a -> Exp a-min = liftM2 A.min--max :: (MultiValue.Real a) => Exp a -> Exp a -> Exp a-max = liftM2 A.max-- zip :: (Value val) => val a -> val b -> val (a, b) zip = lift2 MultiValue.zip @@ -135,10 +128,10 @@ snd = lift1 MultiValue.snd mapFst :: (Exp a -> Exp b) -> Exp (a, c) -> Exp (b, c)-mapFst f = modify (atom, atom) $ TupleHT.mapFst f+mapFst f = liftM (MultiValue.mapFstF (unliftM1 f)) mapSnd :: (Exp b -> Exp c) -> Exp (a, b) -> Exp (a, c)-mapSnd f = modify (atom, atom) $ TupleHT.mapSnd f+mapSnd f = liftM (MultiValue.mapSndF (unliftM1 f)) swap :: (Value val) => val (a, b) -> val (b, a) swap = lift1 MultiValue.swap@@ -160,13 +153,13 @@ thd3 = lift1 MultiValue.thd3 mapFst3 :: (Exp a0 -> Exp a1) -> Exp (a0,b,c) -> Exp (a1,b,c)-mapFst3 f = modify (atom, atom, atom) $ TupleHT.mapFst3 f+mapFst3 f = liftM (MultiValue.mapFst3F (unliftM1 f)) mapSnd3 :: (Exp b0 -> Exp b1) -> Exp (a,b0,c) -> Exp (a,b1,c)-mapSnd3 f = modify (atom, atom, atom) $ TupleHT.mapSnd3 f+mapSnd3 f = liftM (MultiValue.mapSnd3F (unliftM1 f)) mapThd3 :: (Exp c0 -> Exp c1) -> Exp (a,b,c0) -> Exp (a,b,c1)-mapThd3 f = modify (atom, atom, atom) $ TupleHT.mapThd3 f+mapThd3 f = liftM (MultiValue.mapThd3F (unliftM1 f)) modifyMultiValue ::@@ -375,10 +368,23 @@ fromRational' = lift0 . MultiValue.fromRational' +boolPFrom8 :: Exp Bool8 -> Exp Bool+boolPFrom8 = lift1 MultiValue.boolPFrom8++bool8FromP :: Exp Bool -> Exp Bool8+bool8FromP = lift1 MultiValue.bool8FromP++intFromBool8 :: (MultiValue.NativeInteger i ir) => Exp Bool8 -> Exp i+intFromBool8 = liftM MultiValue.intFromBool8++floatFromBool8 :: (MultiValue.NativeFloating a ar) => Exp Bool8 -> Exp a+floatFromBool8 = liftM MultiValue.floatFromBool8++ cmp :: (MultiValue.Comparison a) => LLVM.CmpPredicate -> Exp a -> Exp a -> Exp Bool-cmp ord = liftM2 $ MultiValue.cmp ord+cmp ord = liftM2 (MultiValue.cmp ord) infix 4 ==*, /=*, <*, <=*, >*, >=* @@ -392,6 +398,11 @@ (<=*) = cmp LLVM.CmpLE +min, max :: (MultiValue.Real a) => Exp a -> Exp a -> Exp a+min = liftM2 A.min+max = liftM2 A.max++ true, false :: Exp Bool true = cons True false = cons False@@ -457,7 +468,8 @@ abs = liftM MultiValue.abs signum = liftM MultiValue.signum -instance (MultiValue.Field a, MultiValue.Real a, MultiValue.RationalConstant a) =>+instance+ (MultiValue.Field a, MultiValue.Real a, MultiValue.RationalConstant a) => Fractional (Exp a) where fromRational n = lift0 (MultiValue.fromRational' n) (/) = liftM2 MultiValue.fdiv
+ src/Data/Array/Knead/Expression/Vector.hs view
@@ -0,0 +1,110 @@+module Data.Array.Knead.Expression.Vector where++import qualified Data.Array.Knead.Expression as Expr+import Data.Array.Knead.Expression (Exp)++import qualified LLVM.Extra.Multi.Value.Vector as MultiValueVec+import qualified LLVM.Extra.Multi.Value as MultiValue+import qualified LLVM.Extra.Multi.Vector as MultiVector+import qualified LLVM.Core as LLVM++import Prelude hiding (replicate, zip, fst, snd)+++cons ::+ (LLVM.Positive n, MultiVector.C a) =>+ LLVM.Vector n a -> Exp (LLVM.Vector n a)+cons = Expr.lift0 . MultiValueVec.cons++fst ::+ (LLVM.Positive n, MultiVector.C a, MultiVector.C b) =>+ Exp (LLVM.Vector n (a,b)) -> Exp (LLVM.Vector n a)+fst = Expr.lift1 MultiValueVec.fst++snd ::+ (LLVM.Positive n, MultiVector.C a, MultiVector.C b) =>+ Exp (LLVM.Vector n (a,b)) -> Exp (LLVM.Vector n b)+snd = Expr.lift1 MultiValueVec.snd++swap ::+ (LLVM.Positive n, MultiVector.C a, MultiVector.C b) =>+ Exp (LLVM.Vector n (a,b)) -> Exp (LLVM.Vector n (b,a))+swap = Expr.lift1 MultiValueVec.swap++mapFst ::+ (Exp (LLVM.Vector n a0) -> Exp (LLVM.Vector n a1)) ->+ Exp (LLVM.Vector n (a0,b)) -> Exp (LLVM.Vector n (a1,b))+mapFst f =+ Expr.liftM+ (MultiValue.liftM+ (\(a0,b) -> do+ MultiValue.Cons a1 <- Expr.unliftM1 f $ MultiValue.Cons a0+ return (a1,b)))++mapSnd ::+ (Exp (LLVM.Vector n b0) -> Exp (LLVM.Vector n b1)) ->+ Exp (LLVM.Vector n (a,b0)) -> Exp (LLVM.Vector n (a,b1))+mapSnd f =+ Expr.liftM+ (MultiValue.liftM+ (\(a,b0) -> do+ MultiValue.Cons b1 <- Expr.unliftM1 f $ MultiValue.Cons b0+ return (a,b1)))+++fst3 ::+ (LLVM.Positive n, MultiVector.C a, MultiVector.C b, MultiVector.C c) =>+ Exp (LLVM.Vector n (a,b,c)) -> Exp (LLVM.Vector n a)+fst3 = Expr.lift1 MultiValueVec.fst3++snd3 ::+ (LLVM.Positive n, MultiVector.C a, MultiVector.C b, MultiVector.C c) =>+ Exp (LLVM.Vector n (a,b,c)) -> Exp (LLVM.Vector n b)+snd3 = Expr.lift1 MultiValueVec.snd3++thd3 ::+ (LLVM.Positive n, MultiVector.C a, MultiVector.C b, MultiVector.C c) =>+ Exp (LLVM.Vector n (a,b,c)) -> Exp (LLVM.Vector n c)+thd3 = Expr.lift1 MultiValueVec.thd3+++zip ::+ (LLVM.Positive n, MultiVector.C a, MultiVector.C b) =>+ Exp (LLVM.Vector n a) -> Exp (LLVM.Vector n b) ->+ Exp (LLVM.Vector n (a,b))+zip = Expr.lift2 MultiValueVec.zip++zip3 ::+ (LLVM.Positive n, MultiVector.C a, MultiVector.C b, MultiVector.C c) =>+ Exp (LLVM.Vector n a) -> Exp (LLVM.Vector n b) -> Exp (LLVM.Vector n c) ->+ Exp (LLVM.Vector n (a,b,c))+zip3 = Expr.lift3 MultiValueVec.zip3+++replicate ::+ (LLVM.Positive n, MultiVector.C a) =>+ Exp a -> Exp (LLVM.Vector n a)+replicate = Expr.liftM MultiValueVec.replicate++take ::+ (LLVM.Positive n, LLVM.Positive m, MultiVector.Select a) =>+ Exp (LLVM.Vector n a) -> Exp (LLVM.Vector m a)+take = Expr.liftM MultiValueVec.take++takeRev ::+ (LLVM.Positive n, LLVM.Positive m, MultiVector.Select a) =>+ Exp (LLVM.Vector n a) -> Exp (LLVM.Vector m a)+takeRev = Expr.liftM MultiValueVec.takeRev+++cmp ::+ (LLVM.Positive n, MultiVector.Comparison a) =>+ LLVM.CmpPredicate ->+ Exp (LLVM.Vector n a) -> Exp (LLVM.Vector n a) -> Exp (LLVM.Vector n Bool)+cmp ord = Expr.liftM2 (MultiValueVec.cmp ord)++select ::+ (LLVM.Positive n, MultiVector.Select a) =>+ Exp (LLVM.Vector n Bool) ->+ Exp (LLVM.Vector n a) -> Exp (LLVM.Vector n a) -> Exp (LLVM.Vector n a)+select = Expr.liftM3 MultiValueVec.select
− src/Data/Array/Knead/Index/Linear.hs
@@ -1,558 +0,0 @@-{-# LANGUAGE Rank2Types #-}-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE EmptyDataDecls #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-module Data.Array.Knead.Index.Linear (- C(switch),- switchInt,- intersect,- value,- constant,- paramWith,- tunnel,- flattenIndex,- peek,- poke,- computeSize,-- Struct,- T(..),- Z(Z), z,- (:.)((:.)),- Shape, shape,- Index, index,- cons, (#:.),- head,- tail,- switchR,- loadMultiValue,- storeMultiValue,- ) where--import qualified Data.Array.Knead.Index.Nested.Shape as Shape-import qualified Data.Array.Knead.Index.Linear.Int as Index--import qualified Data.Array.Knead.Parameter as Param-import qualified Data.Array.Knead.Expression as Expr-import Data.Array.Knead.Expression (Exp, )--import qualified LLVM.Extra.Multi.Value.Memory as MultiValueMemory-import qualified LLVM.Extra.Multi.Value as MultiValue-import qualified LLVM.Extra.Arithmetic as A-import qualified LLVM.Extra.Control as C-import LLVM.Extra.Multi.Value (Atom, )--import qualified LLVM.Util.Loop as Loop-import qualified LLVM.Core as LLVM--import qualified Foreign.Storable as St-import Foreign.Storable.FixedArray (sizeOfArray, )-import Foreign.Marshal.Array (advancePtr, )-import Foreign.Ptr (Ptr, castPtr, )--import Control.Monad (liftM2, )-import Data.Word (Word32, )--import Prelude hiding (min, head, tail, )---class C ix where- switch ::- f Z ->- (forall ix0 i. (C ix0, Index.Single i) => f (ix0 :. i)) ->- f ix--instance C Z where- switch x _ = x--instance (C ix0, Index.Single i) => C (ix0 :. i) where- switch _ x = x---newtype SwitchInt f ix i = SwitchInt {runSwitchInt :: f (ix :. i)}--switchInt ::- (C ix) =>- f Z ->- (forall ix0. (C ix0) => f (ix0 :. Index.Int)) ->- f ix-switchInt z0 cons0 =- switch z0- (runSwitchInt $ Index.switchSingle (SwitchInt cons0))---newtype Op2 tag sh = Op2 {runOp2 :: Exp (T tag sh) -> Exp (T tag sh) -> Exp (T tag sh)}--intersect :: C sh => Exp (Shape sh) -> Exp (Shape sh) -> Exp (Shape sh)-intersect =- runOp2 $- switchInt- (Op2 $ \z0 _ -> z0)- (Op2 $- switchR $ \is i ->- switchR $ \js j ->- intersect is js #:. Expr.min i j)---_value :: (C sh, MultiValue.C sh) => sh -> Exp sh-_value = Expr.lift0 . MultiValue.cons---newtype MakeValue val tag sh = MakeValue {runMakeValue :: T tag sh -> val (T tag sh)}--value :: (C sh, Expr.Value val) => T tag sh -> val (T tag sh)-value =- runMakeValue $- switchInt- (MakeValue $ \(Cons Z) -> z)- (MakeValue $ \(Cons (t:.h)) ->- value (Cons t) #:. Expr.lift0 (MultiValue.cons h))--paramWith ::- (C sh, Expr.Value val) =>- Param.T p (T tag sh) ->- (forall parameters.- (St.Storable parameters,- MultiValueMemory.C parameters) =>- (p -> parameters) ->- (MultiValue.T parameters -> val (T tag sh)) ->- a) ->- a-paramWith p f =- case tunnel p of- Param.Tunnel get val -> f get (Expr.lift0 . val)--tunnel :: (C sh) => Param.T p (T tag sh) -> Param.Tunnel p (T tag sh)-tunnel p =- case structFieldsPropF p of- StructFieldsProp -> Param.tunnel value p---data StructFieldsProp sh = LLVM.StructFields (Struct sh) => StructFieldsProp--_structFieldsProp :: (C sh) => f sh -> StructFieldsProp sh-_structFieldsProp _p = structFieldsRec--structFieldsPropF :: (C sh) => f (g sh) -> StructFieldsProp sh-structFieldsPropF _p = structFieldsRec--withStructFieldsPropFF ::- (C sh) => (StructFieldsProp sh -> f (g (h sh))) -> f (g (h sh))-withStructFieldsPropFF f = f structFieldsRec--structFieldsRec :: (C sh) => StructFieldsProp sh-structFieldsRec =- switchInt- StructFieldsProp- (succStructFieldsProp structFieldsRec)--succStructFieldsProp ::- StructFieldsProp sh -> StructFieldsProp (sh:.Index.Int)-succStructFieldsProp StructFieldsProp = StructFieldsProp---data Z = Z- deriving (Eq, Ord, Read, Show)---infixl 3 :., #:.--data tail :. head = !tail :. !head- deriving (Eq, Ord, Read, Show)---newtype T tag sh = Cons {decons :: sh}--data ShapeTag-data IndexTag--type Shape = T ShapeTag-type Index = T IndexTag--shape :: sh -> Shape sh-shape = Cons--index :: ix -> Index ix-index = Cons---(#:.) :: (Expr.Value val) => val (T tag sh) -> val i -> val (T tag (sh:.i))-(#:.) = cons--cons :: (Expr.Value val) => val (T tag sh) -> val i -> val (T tag (sh:.i))-cons =- Expr.lift2 $- \(MultiValue.Cons t) (MultiValue.Cons h) ->- MultiValue.Cons (t,h)--z :: (Expr.Value val) => val (T tag Z)-z = Expr.lift0 $ MultiValue.Cons ()--head :: (Expr.Value val) => val (T tag (sh:.i)) -> val i-head = Expr.lift1 $ \(MultiValue.Cons (_t,h)) -> MultiValue.Cons h--tail :: (Expr.Value val) => val (T tag (sh:.i)) -> val (T tag sh)-tail = Expr.lift1 $ \(MultiValue.Cons (t,_h)) -> MultiValue.Cons t--switchR ::- Expr.Value val =>- (val (T tag sh) -> val i -> a) -> val (T tag (sh :. i)) -> a-switchR f ix = f (tail ix) (head ix)---instance (tag ~ ShapeTag, sh ~ Z) => Shape.Scalar (T tag sh) where- scalar = Expr.lift0 $ MultiValue.Cons ()- zeroIndex _ = Expr.lift0 $ MultiValue.Cons ()---type family PatternTuple pattern-type family Decomposed (f :: * -> *) tag pattern--type instance PatternTuple (sh:.s) =- PatternTuple sh :. MultiValue.PatternTuple s--type instance Decomposed f tag (sh:.s) =- Decomposed f tag sh :. MultiValue.Decomposed f s--type instance PatternTuple (Atom sh) = sh--type instance Decomposed f tag (Atom sh) = f (T tag sh)---class- (Expr.Composed (Decomposed Exp tag pattern) ~ T tag (PatternTuple pattern)) =>- Decompose tag pattern where- decompose ::- T tag pattern -> Exp (T tag (PatternTuple pattern)) ->- Decomposed Exp tag pattern--instance Decompose tag (Atom sh) where- decompose (Cons _atom) x = x--instance (Decompose tag sh, Expr.Decompose s) => Decompose tag (sh :. s) where- decompose (Cons (psh:.ps)) x =- decompose (Cons psh) (tail x) :. Expr.decompose ps (head x)---type instance MultiValue.PatternTuple (T tag sh) = T tag (PatternTuple sh)--type instance MultiValue.Decomposed f (T tag sh) = Decomposed f tag sh---type family Unwrap sh-type instance Unwrap (T tag sh) = sh--type family Tag sh-type instance Tag (T tag sh) = tag--instance- (Expr.Compose sh,- Expr.Composed sh ~ T (Tag (Expr.Composed sh)) (Unwrap (Expr.Composed sh)),- Expr.Compose s) =>- Expr.Compose (sh :. s) where- type Composed (sh :. s) =- T (Tag (Expr.Composed sh))- (Unwrap (Expr.Composed sh) :. Expr.Composed s)- compose (sh :. s) = cons (Expr.compose sh) (Expr.compose s)--instance (Decompose tag sh) => Expr.Decompose (T tag sh) where- decompose = decompose----instance (C sh) => St.Storable (T tag sh) where- sizeOf (Cons sh) = sizeOfArray (rank sh) (0::Word32)- alignment (Cons _sh) = St.alignment (0::Word32)- poke ptr = poke (castPtr ptr) . decons- peek = fmap Cons . peek . castPtr---type family Repr (f :: * -> *) sh-type instance Repr f Z = ()-type instance Repr f (tail :. head) = (Repr f tail, MultiValue.Repr f head)--instance (C sh) => MultiValue.C (T tag sh) where- type Repr f (T tag sh) = Repr f sh- cons = value- undef = constant $ MultiValue.undef- zero = constant $ MultiValue.zero- addPhis = addPhis- phis = phis--instance (tag ~ ShapeTag, C sh) => Shape.C (T tag sh) where- type Index (T tag sh) = Index sh- size = fromIntegral . size . decons- sizeCode = computeSize- intersectCode = Expr.unliftM2 intersect- flattenIndexRec sh ix =- -- a joint implementation would not be more efficient- liftM2 (,)- (computeSize sh)- (flattenIndex sh ix)- loop = loop---type family Struct sh-type instance Struct Z = ()-type instance Struct (sh :. Index.Int) = (Word32, Struct sh)--instance- (C sh, LLVM.StructFields (Struct sh)) =>- MultiValueMemory.C (T tag sh) where- type Struct (T tag sh) = LLVM.Struct (Struct sh)- load = loadMultiValue- store = storeMultiValue--loadMultiValue ::- (C sh) =>- LLVM.Value (Ptr (LLVM.Struct (Struct sh))) ->- LLVM.CodeGenFunction r (MultiValue.T (T tag sh))-loadMultiValue ptr =- withStructFieldsPropFF $ \StructFieldsProp ->- load =<< castPtrValue ptr--storeMultiValue ::- (C sh) =>- MultiValue.T (T tag sh) ->- LLVM.Value (Ptr (LLVM.Struct (Struct sh))) -> LLVM.CodeGenFunction r ()-storeMultiValue x ptr =- case structFieldsPropF x of- StructFieldsProp -> store x =<< castPtrValue ptr---newtype FlattenIndex r sh =- FlattenIndex {- runFlattenIndex ::- MultiValue.T (Shape sh) -> MultiValue.T (Index sh) ->- LLVM.CodeGenFunction r (LLVM.Value Word32)- }--flattenIndex ::- (C sh) =>- MultiValue.T (Shape sh) -> MultiValue.T (Index sh) ->- LLVM.CodeGenFunction r (LLVM.Value Word32)-flattenIndex =- runFlattenIndex $- switchInt- (FlattenIndex $ \_zerosh _zeroix -> return A.zero)- (FlattenIndex $- switchR $ \sh (MultiValue.Cons s) ->- switchR $ \ix (MultiValue.Cons i) ->- A.add i =<< A.mul s =<< flattenIndex sh ix)---newtype Rank sh = Rank {runRank :: sh -> Int}--rank :: (C sh) => sh -> Int-rank =- runRank $- switch- (Rank $ const 0)- (Rank $ succ . rank . (\(sh :. _s) -> sh))---newtype Peek sh = Peek {runPeek :: Ptr Word32 -> IO sh}--peek :: (C sh) => Ptr Word32 -> IO sh-peek =- runPeek $- switchInt- (Peek $ const $ return Z)- (Peek $ \ptr -> do- h <- St.peek ptr- t <- peek $ advancePtr ptr 1- return (t :. Index.Int h))---newtype Poke sh = Poke {runPoke :: Ptr Word32 -> sh -> IO ()}--poke :: (C sh) => Ptr Word32 -> sh -> IO ()-poke =- runPoke $- switchInt- (Poke $ const $ const $ return ())- (Poke $ \ptr (sh :. Index.Int i) -> do- St.poke ptr i- poke (advancePtr ptr 1) sh)---castPtrValue ::- (LLVM.StructFields sh) =>- LLVM.Value (Ptr (LLVM.Struct sh)) ->- LLVM.CodeGenFunction r (LLVM.Value (Ptr Word32))-castPtrValue = LLVM.bitcast--newtype Load r tag sh =- Load {- runLoad ::- LLVM.Value (Ptr Word32) ->- LLVM.CodeGenFunction r (MultiValue.T (T tag sh))- }--load ::- (C sh) =>- LLVM.Value (Ptr Word32) ->- LLVM.CodeGenFunction r (MultiValue.T (T tag sh))-load =- runLoad $- switchInt- (Load $ const $ return z)- (Load $ \ptr -> do- h <- LLVM.load ptr- t <- load =<< A.advanceArrayElementPtr ptr- return (t #:. MultiValue.Cons h))---newtype Store r tag sh =- Store {- runStore ::- MultiValue.T (T tag sh) ->- LLVM.Value (Ptr Word32) ->- LLVM.CodeGenFunction r ()- }--store ::- (C sh) =>- MultiValue.T (T tag sh) ->- LLVM.Value (Ptr Word32) ->- LLVM.CodeGenFunction r ()-store =- runStore $- switchInt- (Store $ \_z _ptr -> return ())- (Store $ switchR $ \sh (MultiValue.Cons k) ptr -> do- LLVM.store k ptr- store sh =<< A.advanceArrayElementPtr ptr)---newtype Size sh =- Size {- runSize :: sh -> Word32- }--size :: (C sh) => sh -> Word32-size =- runSize $- switchInt- (Size $ \_z -> 1)- (Size $ \(sh :. Index.Int k) -> k * size sh)---newtype ComputeSize r sh =- ComputeSize {- runComputeSize ::- MultiValue.T (Shape sh) ->- LLVM.CodeGenFunction r (LLVM.Value Word32)- }--computeSize ::- (C sh) =>- MultiValue.T (Shape sh) ->- LLVM.CodeGenFunction r (LLVM.Value Word32)-computeSize =- runComputeSize $- switchInt- (ComputeSize $ \_z -> return A.one)- (ComputeSize $ switchR $ \sh (MultiValue.Cons k) ->- A.mul k =<< computeSize sh)---newtype- Constant val tag sh =- Constant {getConstant :: val Index.Int -> val (T tag sh)}--constant :: (C sh, Expr.Value val) => val Index.Int -> val (T tag sh)-constant =- getConstant $- switchInt- (Constant $ const z)- (Constant $ \x -> constant x #:. x)---newtype AddPhis r tag sh =- AddPhis {- runAddPhis ::- LLVM.BasicBlock ->- MultiValue.T (T tag sh) ->- MultiValue.T (T tag sh) ->- LLVM.CodeGenFunction r ()- }--addPhis ::- (C sh) =>- LLVM.BasicBlock ->- MultiValue.T (T tag sh) ->- MultiValue.T (T tag sh) ->- LLVM.CodeGenFunction r ()-addPhis =- runAddPhis $- switchInt- (AddPhis $ \_ _ _ -> return ())- (AddPhis $ \bb ->- switchR $ \hx tx ->- switchR $ \hy ty ->- MultiValue.addPhis bb tx ty >>- addPhis bb hx hy)---newtype Phis r tag sh =- Phis {- runPhis ::- LLVM.BasicBlock ->- MultiValue.T (T tag sh) ->- LLVM.CodeGenFunction r (MultiValue.T (T tag sh))- }--phis ::- (C sh) =>- LLVM.BasicBlock ->- MultiValue.T (T tag sh) ->- LLVM.CodeGenFunction r (MultiValue.T (T tag sh))-phis =- runPhis $- switchInt- (Phis $ \_ -> return)- (Phis $ \bb ->- switchR $ \h t ->- liftM2 (#:.)- (phis bb h)- (MultiValue.phis bb t))---newtype Loop r state sh =- Loop {- runLoop ::- (MultiValue.T (Index sh) ->- state ->- LLVM.CodeGenFunction r state) ->- MultiValue.T (Shape sh) ->- state ->- LLVM.CodeGenFunction r state- }--loop ::- (C sh, Loop.Phi state) =>- (MultiValue.T (Index sh) ->- state ->- LLVM.CodeGenFunction r state) ->- MultiValue.T (Shape sh) ->- state ->- LLVM.CodeGenFunction r state-loop =- runLoop $- switchInt- (Loop $ \code _z -> code z)- (Loop $ \code -> switchR $ \sh (MultiValue.Cons n) ->- loop- (\ix ptrStart ->- fmap fst $- C.fixedLengthLoop n (ptrStart, A.zero) $ \(ptr, k) ->- liftM2 (,)- (code (ix #:. MultiValue.Cons k) ptr)- (A.inc k))- sh)
− src/Data/Array/Knead/Index/Linear/Int.hs
@@ -1,59 +0,0 @@-{-# LANGUAGE TypeFamilies #-}-module Data.Array.Knead.Index.Linear.Int (- Single(..),- Int(Int), cons, decons,- ) where--import qualified Data.Array.Knead.Expression as Expr--import qualified LLVM.Extra.Multi.Value as MultiValue-import qualified LLVM.Extra.Arithmetic as A--import Data.Word (Word32, )--import Prelude hiding (Int, head, tail, )---newtype Int = Int Word32--cons :: (Expr.Value val) => val Word32 -> val Int-cons = Expr.lift1 $ \(MultiValue.Cons x) -> MultiValue.Cons x--decons :: (Expr.Value val) => val Int -> val Word32-decons = Expr.lift1 $ \(MultiValue.Cons x) -> MultiValue.Cons x---class Single ix where- switchSingle :: f Int -> f ix--instance Single Int where- switchSingle x = x---instance MultiValue.C Int where- type Repr f Int = f Word32- cons (Int x) = MultiValue.consPrimitive x- undef = MultiValue.undefPrimitive- zero = MultiValue.zeroPrimitive- phis = MultiValue.phisPrimitive- addPhis = MultiValue.addPhisPrimitive--instance MultiValue.Additive Int where- add = MultiValue.liftM2 A.add- sub = MultiValue.liftM2 A.sub- neg = MultiValue.liftM A.neg--instance MultiValue.PseudoRing Int where- mul = MultiValue.liftM2 A.mul--instance MultiValue.Real Int where- min = MultiValue.liftM2 A.min- max = MultiValue.liftM2 A.max- abs = MultiValue.liftM A.abs- signum = MultiValue.liftM A.signum--instance MultiValue.IntegerConstant Int where- fromInteger' = cons . A.fromInteger'--instance MultiValue.Comparison Int where- cmp mode = MultiValue.liftM2 $ A.cmp mode
− src/Data/Array/Knead/Index/Nested/Shape.hs
@@ -1,505 +0,0 @@-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE Rank2Types #-}-module Data.Array.Knead.Index.Nested.Shape (- C(..),- value,- paramWith,- load,- intersect,- flattenIndex,-- Range(..),- Shifted(..),-- Scalar(..),- ) where--import qualified Data.Array.Knead.Expression as Expr-import qualified Data.Array.Knead.Parameter as Param-import Data.Array.Knead.Expression (Exp, )--import qualified LLVM.Extra.Multi.Value.Memory as MultiMem-import qualified LLVM.Extra.Multi.Value as MultiValue-import qualified LLVM.Extra.Arithmetic as A-import qualified LLVM.Extra.Control as C-import LLVM.Extra.Multi.Value (atom)-import LLVM.Extra.Monad (liftR2)--import qualified LLVM.Util.Loop as Loop-import qualified LLVM.Core as LLVM--import qualified Type.Data.Num.Decimal as TypeNum--import Foreign.Storable- (Storable, sizeOf, alignment, poke, peek, pokeElemOff, peekElemOff)-import Foreign.Ptr (Ptr, castPtr)--import Data.Word (Word8, Word16, Word32, Word64)-import Data.Int (Int8, Int16, Int32, Int64)--import qualified Control.Monad.HT as Monad-import Control.Applicative ((<$>))---value :: (C sh, Expr.Value val) => sh -> val sh-value = Expr.lift0 . MultiValue.cons--paramWith ::- (Storable b, MultiMem.C b, Expr.Value val) =>- Param.T p b ->- (forall parameters.- (Storable parameters, MultiMem.C parameters) =>- (p -> parameters) ->- (MultiValue.T parameters -> val b) ->- a) ->- a-paramWith p f =- Param.withMulti p (\get val -> f get (Expr.lift0 . val))--load ::- (MultiMem.C sh) =>- f sh -> LLVM.Value (Ptr (MultiMem.Struct sh)) ->- LLVM.CodeGenFunction r (MultiValue.T sh)-load _ = MultiMem.load--intersect :: (C sh) => Exp sh -> Exp sh -> Exp sh-intersect = Expr.liftM2 intersectCode--flattenIndex ::- (C sh) =>- MultiValue.T sh -> MultiValue.T (Index sh) ->- LLVM.CodeGenFunction r (LLVM.Value Word32)-flattenIndex sh ix =- fmap snd $ flattenIndexRec sh ix--class (MultiValue.C sh) => C sh where- type Index sh :: *- {-- It would be better to restrict zipWith to matching shapes- and turn shape intersection into a bound check.- -}- intersectCode ::- MultiValue.T sh -> MultiValue.T sh ->- LLVM.CodeGenFunction r (MultiValue.T sh)- sizeCode ::- MultiValue.T sh ->- LLVM.CodeGenFunction r (LLVM.Value Word32)- size :: sh -> Int- {- |- Result is @(size, flattenedIndex)@.- @size@ must equal the result of 'sizeCode'.- We use this for sharing intermediate results.- -}- flattenIndexRec ::- MultiValue.T sh -> MultiValue.T (Index sh) ->- LLVM.CodeGenFunction r (LLVM.Value Word32, LLVM.Value Word32)- loop ::- (Index sh ~ ix, Loop.Phi state) =>- (MultiValue.T ix -> state -> LLVM.CodeGenFunction r state) ->- MultiValue.T sh -> state -> LLVM.CodeGenFunction r state---instance C () where- type Index () = ()- intersectCode _ _ = return $ MultiValue.cons ()- sizeCode _ = return A.one- size _ = 1- flattenIndexRec _ _ = return (A.one, A.zero)- loop = id---class C sh => Scalar sh where- scalar :: (Expr.Value val) => val sh- zeroIndex :: (Expr.Value val) => f sh -> val (Index sh)--instance Scalar () where- scalar = Expr.lift0 $ MultiValue.Cons ()- zeroIndex _ = Expr.lift0 $ MultiValue.Cons ()---loopPrimitive ::- (MultiValue.Repr LLVM.Value j ~ LLVM.Value j,- Num j, LLVM.IsConst j, LLVM.IsInteger j,- LLVM.CmpRet j, LLVM.CmpResult j ~ Bool,- MultiValue.Additive i, MultiValue.IntegerConstant i,- Loop.Phi state) =>- (MultiValue.T i -> state -> LLVM.CodeGenFunction r state) ->- MultiValue.T j -> state -> LLVM.CodeGenFunction r state-loopPrimitive code (MultiValue.Cons n) ptrStart =- loopStart code n MultiValue.zero ptrStart--loopStart ::- (Num j, LLVM.IsConst j, LLVM.IsInteger j,- LLVM.CmpRet j, LLVM.CmpResult j ~ Bool,- MultiValue.Additive i, MultiValue.IntegerConstant i,- Loop.Phi state) =>- (MultiValue.T i -> state -> LLVM.CodeGenFunction r state) ->- LLVM.Value j ->- MultiValue.T i -> state -> LLVM.CodeGenFunction r state-loopStart code n start ptrStart =- fmap fst $- C.fixedLengthLoop n (ptrStart, start) $ \(ptr, k) ->- Monad.lift2 (,) (code k ptr) (MultiValue.inc k)--instance C Word32 where- type Index Word32 = Word32- intersectCode = MultiValue.min- sizeCode (MultiValue.Cons n) = return n- size = fromIntegral- flattenIndexRec (MultiValue.Cons n) (MultiValue.Cons i) = return (n, i)- loop = loopPrimitive--instance C Word64 where- type Index Word64 = Word64- intersectCode = MultiValue.min- sizeCode (MultiValue.Cons n) = LLVM.trunc n- size = fromIntegral- flattenIndexRec (MultiValue.Cons n) (MultiValue.Cons i) =- Monad.lift2 (,) (LLVM.trunc n) (LLVM.trunc i)- loop = loopPrimitive---{- |-Array dimensions and indexes cannot be negative,-but computations in indices may temporarily yield negative values-or we want to add negative values to indices.--Maybe we should better have type Index Word64 = Int64?--}-unsigned8 :: LLVM.Value Int8 -> LLVM.CodeGenFunction r (LLVM.Value Word8)-unsigned8 = LLVM.bitcast--instance C Int8 where- type Index Int8 = Int8- intersectCode = MultiValue.min- sizeCode (MultiValue.Cons n) = LLVM.ext =<< unsigned8 n- size = fromIntegral- flattenIndexRec (MultiValue.Cons n) (MultiValue.Cons i) =- Monad.lift2 (,) (LLVM.ext =<< unsigned8 n) (LLVM.ext =<< unsigned8 i)- loop = loopPrimitive--unsigned16 :: LLVM.Value Int16 -> LLVM.CodeGenFunction r (LLVM.Value Word16)-unsigned16 = LLVM.bitcast--instance C Int16 where- type Index Int16 = Int16- intersectCode = MultiValue.min- sizeCode (MultiValue.Cons n) = LLVM.ext =<< unsigned16 n- size = fromIntegral- flattenIndexRec (MultiValue.Cons n) (MultiValue.Cons i) =- Monad.lift2 (,) (LLVM.ext =<< unsigned16 n) (LLVM.ext =<< unsigned16 i)- loop = loopPrimitive--instance C Int32 where- type Index Int32 = Int32- intersectCode = MultiValue.min- sizeCode (MultiValue.Cons n) = LLVM.bitcast n- size = fromIntegral- flattenIndexRec (MultiValue.Cons n) (MultiValue.Cons i) =- Monad.lift2 (,) (LLVM.bitcast n) (LLVM.bitcast i)- loop = loopPrimitive--instance C Int64 where- type Index Int64 = Int64- intersectCode = MultiValue.min- sizeCode (MultiValue.Cons n) = LLVM.trunc n- size = fromIntegral- flattenIndexRec (MultiValue.Cons n) (MultiValue.Cons i) =- Monad.lift2 (,) (LLVM.trunc n) (LLVM.trunc i)- loop = loopPrimitive---{- |-'Range' denotes an inclusive range like-those of the Haskell 98 standard @Array@ type from the @array@ package.-E.g. the shape type @(Range Int32, Range Int64)@-is equivalent to the ix type @(Int32, Int64)@ for @Array@s.--}-data Range n = Range n n--singletonRange :: n -> Range n-singletonRange n = Range n n---{-# INLINE castToElemPtr #-}-castToElemPtr :: Ptr (f a) -> Ptr a-castToElemPtr = castPtr---- cf. sample-frame:Stereo-instance Storable n => Storable (Range n) where- {-# INLINE sizeOf #-}- {-# INLINE alignment #-}- {-# INLINE peek #-}- {-# INLINE poke #-}- sizeOf ~(Range l r) = sizeOf l + mod (- sizeOf l) (alignment r) + sizeOf r- alignment ~(Range l _) = alignment l- poke p (Range l r) =- let q = castToElemPtr p- in poke q l >> pokeElemOff q 1 r- peek p =- let q = castToElemPtr p- in Monad.lift2 Range (peek q) (peekElemOff q 1)---class- (MultiValue.Additive n, MultiValue.Real n, MultiValue.IntegerConstant n) =>- ToSize n where- toSize :: MultiValue.T n -> LLVM.CodeGenFunction r (LLVM.Value Word32)--instance ToSize Word32 where toSize (MultiValue.Cons n) = LLVM.adapt n-instance ToSize Word64 where toSize (MultiValue.Cons n) = LLVM.adapt n-instance ToSize Int32 where toSize (MultiValue.Cons n) = LLVM.bitcast n-instance ToSize Int64 where toSize (MultiValue.Cons n) = LLVM.trunc n--rangeSize ::- (ToSize n) =>- Range (MultiValue.T n) -> LLVM.CodeGenFunction r (LLVM.Value Word32)-rangeSize (Range from to) =- toSize =<< MultiValue.inc =<< MultiValue.sub to from--unzipRange :: MultiValue.T (Range n) -> Range (MultiValue.T n)-unzipRange (MultiValue.Cons (Range from to)) =- Range (MultiValue.Cons from) (MultiValue.Cons to)--zipRange :: MultiValue.T n -> MultiValue.T n -> MultiValue.T (Range n)-zipRange (MultiValue.Cons from) (MultiValue.Cons to) =- MultiValue.Cons (Range from to)--instance (MultiValue.C n) => MultiValue.C (Range n) where- type Repr f (Range n) = Range (MultiValue.Repr f n)- cons (Range from to) = zipRange (MultiValue.cons from) (MultiValue.cons to)- undef = MultiValue.compose $ singletonRange MultiValue.undef- zero = MultiValue.compose $ singletonRange MultiValue.zero- phis bb a =- case unzipRange a of- Range a0 a1 ->- Monad.lift2 zipRange (MultiValue.phis bb a0) (MultiValue.phis bb a1)- addPhis bb a b =- case (unzipRange a, unzipRange b) of- (Range a0 a1, Range b0 b1) ->- MultiValue.addPhis bb a0 b0 >>- MultiValue.addPhis bb a1 b1--type instance- MultiValue.Decomposed f (Range pn) =- Range (MultiValue.Decomposed f pn)-type instance- MultiValue.PatternTuple (Range pn) =- Range (MultiValue.PatternTuple pn)--instance (MultiValue.Compose n) => MultiValue.Compose (Range n) where- type Composed (Range n) = Range (MultiValue.Composed n)- compose (Range from to) =- zipRange (MultiValue.compose from) (MultiValue.compose to)--instance (MultiValue.Decompose pn) => MultiValue.Decompose (Range pn) where- decompose (Range pfrom pto) rng =- case unzipRange rng of- Range from to ->- Range- (MultiValue.decompose pfrom from)- (MultiValue.decompose pto to)--instance (MultiMem.C n) => MultiMem.C (Range n) where- type Struct (Range n) = PairStruct n- decompose = fmap (uncurry zipRange) . decomposeGen- compose x = case unzipRange x of Range n m -> composeGen n m--instance (Integral n, ToSize n) => C (Range n) where- type Index (Range n) = n- intersectCode =- MultiValue.modifyF2 (singletonRange atom) (singletonRange atom) $- \(Range fromN toN) (Range fromM toM) ->- Monad.lift2 Range (MultiValue.max fromN fromM) (MultiValue.min toN toM)- sizeCode = rangeSize . unzipRange- size (Range from to) = fromIntegral $ to-from+1- flattenIndexRec rngValue i =- case unzipRange rngValue of- rng@(Range from _to) ->- Monad.lift2 (,) (rangeSize rng) (toSize =<< MultiValue.sub i from)- loop code rngValue ptrStart =- case unzipRange rngValue of- rng@(Range from _to) -> do- {-- FIXME: rangeSize converts to Word32 which is overly restrictive here.- -}- n <- rangeSize rng- loopStart code n from ptrStart---{- |-'Shifted' denotes a range defined by the start index and the length.--}-data Shifted n = Shifted {shiftedOffset, shiftedSize :: n}--singletonShifted :: n -> Shifted n-singletonShifted n = Shifted n n----- cf. sample-frame:Stereo-instance Storable n => Storable (Shifted n) where- {-# INLINE sizeOf #-}- {-# INLINE alignment #-}- {-# INLINE peek #-}- {-# INLINE poke #-}- sizeOf ~(Shifted l n) = sizeOf l + mod (- sizeOf l) (alignment n) + sizeOf n- alignment ~(Shifted l _) = alignment l- poke p (Shifted l n) =- let q = castToElemPtr p- in poke q l >> pokeElemOff q 1 n- peek p =- let q = castToElemPtr p- in Monad.lift2 Shifted (peek q) (peekElemOff q 1)---unzipShifted :: MultiValue.T (Shifted n) -> Shifted (MultiValue.T n)-unzipShifted (MultiValue.Cons (Shifted from to)) =- Shifted (MultiValue.Cons from) (MultiValue.Cons to)--zipShifted :: MultiValue.T n -> MultiValue.T n -> MultiValue.T (Shifted n)-zipShifted (MultiValue.Cons from) (MultiValue.Cons to) =- MultiValue.Cons (Shifted from to)--instance (MultiValue.C n) => MultiValue.C (Shifted n) where- type Repr f (Shifted n) = Shifted (MultiValue.Repr f n)- cons (Shifted offset len) =- zipShifted (MultiValue.cons offset) (MultiValue.cons len)- undef = MultiValue.compose $ singletonShifted MultiValue.undef- zero = MultiValue.compose $ singletonShifted MultiValue.zero- phis bb a =- case unzipShifted a of- Shifted a0 a1 ->- Monad.lift2 zipShifted- (MultiValue.phis bb a0) (MultiValue.phis bb a1)- addPhis bb a b =- case (unzipShifted a, unzipShifted b) of- (Shifted a0 a1, Shifted b0 b1) ->- MultiValue.addPhis bb a0 b0 >>- MultiValue.addPhis bb a1 b1--type instance- MultiValue.Decomposed f (Shifted pn) =- Shifted (MultiValue.Decomposed f pn)-type instance- MultiValue.PatternTuple (Shifted pn) =- Shifted (MultiValue.PatternTuple pn)--instance (MultiValue.Compose n) => MultiValue.Compose (Shifted n) where- type Composed (Shifted n) = Shifted (MultiValue.Composed n)- compose (Shifted offset len) =- zipShifted (MultiValue.compose offset) (MultiValue.compose len)--instance (MultiValue.Decompose pn) => MultiValue.Decompose (Shifted pn) where- decompose (Shifted poffset plen) rng =- case unzipShifted rng of- Shifted offset len ->- Shifted- (MultiValue.decompose poffset offset)- (MultiValue.decompose plen len)--instance (MultiMem.C n) => MultiMem.C (Shifted n) where- type Struct (Shifted n) = PairStruct n- decompose = fmap (uncurry zipShifted) . decomposeGen- compose x = case unzipShifted x of Shifted n m -> composeGen n m--type PairStruct n = LLVM.Struct (MultiMem.Struct n, (MultiMem.Struct n, ()))--decomposeGen ::- (MultiMem.C n) =>- LLVM.Value (PairStruct n) ->- LLVM.CodeGenFunction r (MultiValue.T n, MultiValue.T n)-decomposeGen nm =- Monad.lift2 (,)- (MultiMem.decompose =<< LLVM.extractvalue nm TypeNum.d0)- (MultiMem.decompose =<< LLVM.extractvalue nm TypeNum.d1)--composeGen ::- (MultiMem.C n) =>- MultiValue.T n -> MultiValue.T n ->- LLVM.CodeGenFunction r (LLVM.Value (PairStruct n))-composeGen n m = do- sn <- MultiMem.compose n- sm <- MultiMem.compose m- rn <- LLVM.insertvalue (LLVM.value LLVM.undef) sn TypeNum.d0- LLVM.insertvalue rn sm TypeNum.d1---instance (Integral n, ToSize n) => C (Shifted n) where- type Index (Shifted n) = n- intersectCode =- MultiValue.modifyF2 (singletonShifted atom) (singletonShifted atom) $- \(Shifted offsetN lenN) (Shifted offsetM lenM) -> do- offset <- MultiValue.max offsetN offsetM- endN <- MultiValue.add offsetN lenN- endM <- MultiValue.add offsetM lenM- end <- MultiValue.min endN endM- Shifted offset <$> MultiValue.sub end offset- sizeCode = toSize . shiftedSize . unzipShifted- size (Shifted _offset len) = fromIntegral len- flattenIndexRec shapeValue i =- case unzipShifted shapeValue of- Shifted offset len ->- Monad.lift2 (,) (toSize len) (toSize =<< MultiValue.sub i offset)- loop code rngValue ptrStart =- case unzipShifted rngValue of- Shifted from len -> do- n <- toSize len- loopStart code n from ptrStart----instance (C n, C m) => C (n,m) where- type Index (n,m) = (Index n, Index m)- intersectCode a b =- case (MultiValue.unzip a, MultiValue.unzip b) of- ((an,am), (bn,bm)) ->- Monad.lift2 MultiValue.zip- (intersectCode an bn)- (intersectCode am bm)- sizeCode nm =- case MultiValue.unzip nm of- (n,m) -> liftR2 A.mul (sizeCode n) (sizeCode m)- size (n,m) = size n * size m- flattenIndexRec nm ij =- case (MultiValue.unzip nm, MultiValue.unzip ij) of- ((n,m), (i,j)) -> do- (ns, il) <- flattenIndexRec n i- (ms, jl) <- flattenIndexRec m j- Monad.lift2 (,)- (A.mul ns ms)- (A.add jl =<< A.mul ms il)- loop code nm =- case MultiValue.unzip nm of- (n,m) -> loop (\i -> loop (\j -> code (MultiValue.zip i j)) m) n--instance (C n, C m, C l) => C (n,m,l) where- type Index (n,m,l) = (Index n, Index m, Index l)- intersectCode a b =- case (MultiValue.unzip3 a, MultiValue.unzip3 b) of- ((ai,aj,ak), (bi,bj,bk)) ->- Monad.lift3 MultiValue.zip3- (intersectCode ai bi)- (intersectCode aj bj)- (intersectCode ak bk)- sizeCode nml =- case MultiValue.unzip3 nml of- (n,m,l) ->- liftR2 A.mul (sizeCode n) $- liftR2 A.mul (sizeCode m) (sizeCode l)- size (n,m,l) = size n * size m * size l- flattenIndexRec nml ijk =- case (MultiValue.unzip3 nml, MultiValue.unzip3 ijk) of- ((n,m,l), (i,j,k)) -> do- (ns, il) <- flattenIndexRec n i- (ms, jl) <- flattenIndexRec m j- x0 <- A.add jl =<< A.mul ms il- (ls, kl) <- flattenIndexRec l k- x1 <- A.add kl =<< A.mul ls x0- sz <- A.mul ns =<< A.mul ms ls- return (sz, x1)- loop code nml =- case MultiValue.unzip3 nml of- (n,m,l) ->- loop (\i -> loop (\j -> loop (\k ->- code (MultiValue.zip3 i j k))- l) m) n
src/Data/Array/Knead/Parameter.hs view
@@ -90,6 +90,7 @@ that use the unit type for constants and thus save space in parameter structures. -}+{-# INLINE withTuple #-} withTuple :: (Storable tuple, Class.MakeValueTuple tuple, Class.ValueTuple tuple ~ value, Memory.C value) =>@@ -105,6 +106,7 @@ withTuple (Constant a) f = f (const ()) (\() -> Class.valueTupleOf a) withTuple (Variable v) f = f v id +{-# INLINE withMulti #-} withMulti :: (Storable b, MultiValueMemory.C b) => T p b ->@@ -117,6 +119,7 @@ a withMulti = with MultiValue.cons +{-# INLINE with #-} with :: (Storable b, MultiValueMemory.C b) => (b -> MultiValue.T b) ->
src/Data/Array/Knead/Parameterized/Physical.hs view
@@ -8,7 +8,7 @@ the, render, renderShape,- mapAccumL,+ mapAccumLSimple, foldOuterL, scatter, scatterMaybe,@@ -20,7 +20,7 @@ import qualified Data.Array.Knead.Simple.Physical as Phys import qualified Data.Array.Knead.Simple.Private as Core import qualified Data.Array.Knead.Parameter as Param-import qualified Data.Array.Knead.Index.Nested.Shape as Shape+import qualified Data.Array.Knead.Shape.Nested as Shape import qualified Data.Array.Knead.Expression as Expr import qualified Data.Array.Knead.Code as Code import Data.Array.Knead.Expression (Exp, unExp, )@@ -42,9 +42,9 @@ import Control.Monad.HT ((<=<), ) import Control.Applicative (liftA2, ) import Data.Tuple.HT (mapFst, )-import Data.Word (Word32, ) +{-# INLINE feed #-} feed :: (Shape.C sh, Storable sh, MultiValueMemory.C sh, MultiValueMemory.C a) =>@@ -93,13 +93,13 @@ foreign import ccall safe "dynamic" callShaper ::- Importer (Ptr param -> Ptr shape -> IO Word32)+ Importer (Ptr param -> Ptr shape -> IO Shape.Size) renderShape :: (Shape.C sh, Storable sh, MultiValueMemory.C sh, Storable a, MultiValueMemory.C a) =>- Sym.Array p sh a -> IO (p -> IO (sh, Word32))+ Sym.Array p sh a -> IO (p -> IO (sh, Shape.Size)) renderShape (Sym.Array arr create delete) = do fsh <- compile "renderShape" $@@ -129,7 +129,7 @@ render = PhysHull.render . Sym.arrayHull -mapAccumL ::+mapAccumLSimple :: (Shape.C sh, Storable sh, MultiValueMemory.C sh, Shape.C n, Storable n, MultiValueMemory.C n, MultiValue.C acc,@@ -139,9 +139,9 @@ Sym.Array p sh acc -> Sym.Array p (sh, n) a -> IO (p -> IO (Phys.Array (sh,n) b))-mapAccumL f arrInit arrMap =- PhysHull.mapAccumL $- liftA2 (PhysHull.MapAccumL f)+mapAccumLSimple f arrInit arrMap =+ PhysHull.mapAccumLSimple $+ liftA2 (PhysHull.MapAccumLSimple f) (Sym.arrayHull arrInit) (Sym.arrayHull arrMap)
src/Data/Array/Knead/Parameterized/PhysicalHull.hs view
@@ -2,21 +2,32 @@ {-# LANGUAGE ForeignFunctionInterface #-} module Data.Array.Knead.Parameterized.PhysicalHull ( render,+ MapFilter(..),+ mapFilter,+ FilterOuter(..),+ filterOuter, Scatter(..), scatter, ScatterMaybe(..), scatterMaybe,+ MapAccumLSimple(..),+ mapAccumLSimple,+ MapAccumLSequence(..),+ mapAccumLSequence, MapAccumL(..), mapAccumL, FoldOuterL(..), foldOuterL,+ AddDimension(..),+ addDimension, ) where import qualified Data.Array.Knead.Parameterized.Private as Sym import qualified Data.Array.Knead.Simple.PhysicalPrivate as Priv import qualified Data.Array.Knead.Simple.Physical as Phys import qualified Data.Array.Knead.Simple.Private as Core-import qualified Data.Array.Knead.Index.Nested.Shape as Shape+import qualified Data.Array.Knead.Shape.Nested as Shape+import qualified Data.Array.Knead.Expression as Expr import qualified Data.Array.Knead.Code as Code import Data.Array.Knead.Expression (Exp, unExp, ) import Data.Array.Knead.Code (compile, )@@ -29,26 +40,41 @@ import qualified LLVM.Core as LLVM import Foreign.Marshal.Utils (with, )+import Foreign.Marshal.Array (allocaArray, ) import Foreign.Marshal.Alloc (alloca, )-import Foreign.Storable (Storable, peek, )-import Foreign.ForeignPtr (withForeignPtr, mallocForeignPtrArray, )+import Foreign.Storable (Storable, peek, peekElemOff, )+import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, mallocForeignPtrArray, ) import Foreign.Ptr (FunPtr, Ptr, ) import Control.Exception (bracket, ) import Control.Monad.HT (void, ) import Control.Applicative (liftA2, )-import Data.Word (Word32, ) +mallocArray :: (Storable a) => Shape.Size -> IO (ForeignPtr a)+mallocArray = mallocForeignPtrArray . fromIntegral++withForeignMemPtr ::+ ForeignPtr a -> (Ptr (MultiValueMemory.Struct a) -> IO b) -> IO b+withForeignMemPtr fptr act =+ withForeignPtr fptr $ act . MultiValueMemory.castStructPtr++ type Importer f = FunPtr f -> f foreign import ccall safe "dynamic" callShaper ::- Importer (Ptr param -> Ptr shape -> IO Word32)+ Importer (Ptr param -> Ptr shape -> IO Shape.Size) foreign import ccall safe "dynamic" callFill :: Importer (Ptr param -> Ptr shape -> Ptr am -> IO ()) ++{-+Attention:+The 'fill' function may alter the shape.+An example is 'mapFilter'.+-} materialize :: (Shape.C sh, Storable sh, MultiValueMemory.C sh, Storable a, MultiValueMemory.C a) =>@@ -81,14 +107,121 @@ with param $ \paramPtr -> do let paramMVPtr = MultiValueMemory.castStructPtr paramPtr let shapeMVPtr = MultiValueMemory.castStructPtr shptr- n <- fsh paramMVPtr shapeMVPtr- fptr <- mallocForeignPtrArray (fromIntegral n)- withForeignPtr fptr $- farr paramMVPtr shapeMVPtr . MultiValueMemory.castStructPtr+ fptr <- mallocArray =<< fsh paramMVPtr shapeMVPtr+ withForeignMemPtr fptr $ farr paramMVPtr shapeMVPtr sh <- peek shptr return (Phys.Array sh fptr) +foreign import ccall safe "dynamic" callFillExpArray ::+ Importer (Ptr param -> Ptr final -> Ptr shape -> Ptr am -> IO ())+++materializeExpArray ::+ (Shape.C sh, Storable sh, MultiValueMemory.C sh,+ Storable a, MultiValueMemory.C a,+ Storable b, MultiValueMemory.C b) =>+ String ->+ (core -> Exp sh) ->+ (core ->+ LLVM.Value (Ptr (MultiValueMemory.Struct b)) ->+ LLVM.Value (Ptr (MultiValueMemory.Struct sh)) ->+ LLVM.Value (Ptr (MultiValueMemory.Struct a)) ->+ LLVM.CodeGenFunction () ()) ->+ Sym.Hull p core -> IO (p -> IO (b, Phys.Array sh a))+materializeExpArray name shape fill (Sym.Hull core create delete) = do+ (fsh, farr) <-+ compile name $+ liftA2 (,)+ (Code.createFunction callShaper "shape" $+ \paramPtr resultPtr -> do+ param <- Memory.load paramPtr+ sh <- unExp $ shape $ core param+ MultiValueMemory.store sh resultPtr+ Shape.sizeCode sh >>= LLVM.ret)+ (Code.createFunction callFillExpArray "fill" $+ \paramPtr finalPtr shapePtr bufferPtr -> do+ param <- Memory.load paramPtr+ fill (core param) finalPtr shapePtr bufferPtr+ LLVM.ret ())++ return $ \p ->+ bracket (create p) (delete . fst) $ \(_ctx, param) ->+ alloca $ \shptr ->+ alloca $ \finalPtr ->+ with param $ \paramPtr -> do+ let paramMVPtr = MultiValueMemory.castStructPtr paramPtr+ let finalMVPtr = MultiValueMemory.castStructPtr finalPtr+ let shapeMVPtr = MultiValueMemory.castStructPtr shptr+ fptr <- mallocArray =<< fsh paramMVPtr shapeMVPtr+ withForeignMemPtr fptr $ farr paramMVPtr finalMVPtr shapeMVPtr+ sh <- peek shptr+ final <- peek finalPtr+ return (final, Phys.Array sh fptr)+++foreign import ccall safe "dynamic" callShaper2 ::+ Importer (Ptr param -> Ptr shapeA -> Ptr shapeB -> Ptr Shape.Size -> IO ())++foreign import ccall safe "dynamic" callFill2 ::+ Importer (Ptr param -> Ptr shapeA -> Ptr am -> Ptr shapeB -> Ptr bm -> IO ())+++materialize2 ::+ (Shape.C sha, Storable sha, MultiValueMemory.C sha,+ Shape.C shb, Storable shb, MultiValueMemory.C shb,+ Storable a, MultiValueMemory.C a,+ Storable b, MultiValueMemory.C b) =>+ String ->+ (core -> Exp (sha,shb)) ->+ (core ->+ (LLVM.Value (Ptr (MultiValueMemory.Struct sha)),+ LLVM.Value (Ptr (MultiValueMemory.Struct a))) ->+ (LLVM.Value (Ptr (MultiValueMemory.Struct shb)),+ LLVM.Value (Ptr (MultiValueMemory.Struct b))) ->+ LLVM.CodeGenFunction () ()) ->+ Sym.Hull p core -> IO (p -> IO (Phys.Array sha a, Phys.Array shb b))+materialize2 name shape fill (Sym.Hull core create delete) = do+ (fsh, farr) <-+ compile name $+ liftA2 (,)+ (Code.createFunction callShaper2 "shape" $+ \paramPtr shapeAPtr shapeBPtr sizesPtr -> do+ param <- Memory.load paramPtr+ (sha,shb) <- fmap MultiValue.unzip $ unExp $ shape $ core param+ MultiValueMemory.store sha shapeAPtr+ MultiValueMemory.store shb shapeBPtr+ sizeAPtr <- LLVM.bitcast sizesPtr+ flip LLVM.store sizeAPtr =<< Shape.sizeCode sha+ sizeBPtr <- A.advanceArrayElementPtr sizeAPtr+ flip LLVM.store sizeBPtr =<< Shape.sizeCode shb+ LLVM.ret ())+ (Code.createFunction callFill2 "fill" $+ \paramPtr shapeAPtr bufferAPtr shapeBPtr bufferBPtr -> do+ param <- Memory.load paramPtr+ fill (core param) (shapeAPtr, bufferAPtr) (shapeBPtr, bufferBPtr)+ LLVM.ret ())++ return $ \p ->+ bracket (create p) (delete . fst) $ \(_ctx, param) ->+ alloca $ \shaPtr ->+ alloca $ \shbPtr ->+ allocaArray 2 $ \sizesPtr ->+ with param $ \paramPtr -> do+ let paramMVPtr = MultiValueMemory.castStructPtr paramPtr+ let shapeAMVPtr = MultiValueMemory.castStructPtr shaPtr+ let shapeBMVPtr = MultiValueMemory.castStructPtr shbPtr+ fsh paramMVPtr shapeAMVPtr shapeBMVPtr sizesPtr+ afptr <- mallocArray =<< peekElemOff sizesPtr 0+ bfptr <- mallocArray =<< peekElemOff sizesPtr 1+ withForeignMemPtr afptr $ \aptr ->+ withForeignMemPtr bfptr $ \bptr ->+ farr paramMVPtr shapeAMVPtr aptr shapeBMVPtr bptr+ sha <- peek shaPtr+ shb <- peek shbPtr+ return (Phys.Array sha afptr, Phys.Array shb bfptr)++ render :: (Shape.C sh, Shape.Index sh ~ ix, Storable sh, MultiValueMemory.C sh,@@ -145,40 +278,151 @@ Priv.scatterMaybe accum arrInit arrMap) -data MapAccumL sh n acc a b =+data MapAccumLSimple sh n acc a b =+ MapAccumLSimple {+ mapAccumLSimpleAccum :: Exp acc -> Exp a -> Exp (acc,b),+ mapAccumLSimpleInit :: Core.Array sh acc,+ mapAccumLSimpleArray :: Core.Array (sh, n) a+ }++mapAccumLSimple ::+ (Shape.C sh, Storable sh, MultiValueMemory.C sh,+ Shape.C n, Storable n, MultiValueMemory.C n,+ MultiValue.C acc,+ Storable a, MultiValueMemory.C a,+ Storable b, MultiValueMemory.C b) =>+ Sym.Hull p (MapAccumLSimple sh n acc a b) -> IO (p -> IO (Phys.Array (sh,n) b))+mapAccumLSimple =+ materialize "mapAccumLSimple"+ (Core.shape . mapAccumLSimpleArray)+ (\(MapAccumLSimple f arrInit arrData) ->+ Priv.mapAccumLSimple f arrInit arrData)+++data MapAccumLSequence n acc final a b =+ MapAccumLSequence {+ mapAccumLSequenceAccum :: Exp acc -> Exp a -> Exp (acc,b),+ mapAccumLSequenceFinal :: Exp acc -> Exp final,+ mapAccumLSequenceInit :: Exp acc,+ mapAccumLSequenceArray :: Core.Array n a+ }++-- FIXME: check correct size of array of initial values+mapAccumLSequence ::+ (Shape.C n, Storable n, MultiValueMemory.C n,+ MultiValue.C acc,+ Storable final, MultiValueMemory.C final,+ Storable a, MultiValueMemory.C a,+ Storable b, MultiValueMemory.C b) =>+ Sym.Hull p (MapAccumLSequence n acc final a b) ->+ IO (p -> IO (final, Phys.Array n b))+mapAccumLSequence =+ materializeExpArray "mapAccumLSequence"+ (Core.shape . mapAccumLSequenceArray)+ (\(MapAccumLSequence f final expInit arr) ->+ Priv.mapAccumLSequence f final expInit arr)+++data MapAccumL sh n acc final a b = MapAccumL { mapAccumLAccum :: Exp acc -> Exp a -> Exp (acc,b),+ mapAccumLFinal :: Exp acc -> Exp final, mapAccumLInit :: Core.Array sh acc,- mapAccumLMap :: Core.Array (sh, n) a+ mapAccumLArray :: Core.Array (sh, n) a } +-- FIXME: check correct size of array of initial values mapAccumL :: (Shape.C sh, Storable sh, MultiValueMemory.C sh, Shape.C n, Storable n, MultiValueMemory.C n, MultiValue.C acc,+ Storable final, MultiValueMemory.C final, Storable a, MultiValueMemory.C a, Storable b, MultiValueMemory.C b) =>- Sym.Hull p (MapAccumL sh n acc a b) -> IO (p -> IO (Phys.Array (sh,n) b))+ Sym.Hull p (MapAccumL sh n acc final a b) ->+ IO (p -> IO (Phys.Array sh final, Phys.Array (sh,n) b)) mapAccumL =- materialize "mapAccumL"- (Core.shape . mapAccumLMap)- (\(MapAccumL f arrInit arrData) -> Priv.mapAccumL f arrInit arrData)+ materialize2 "mapAccumL"+ (\core ->+ Expr.zip+ (Core.shape $ mapAccumLInit core)+ (Core.shape $ mapAccumLArray core))+ (\(MapAccumL f final arrInit arrData) ->+ Priv.mapAccumL f final arrInit arrData) data FoldOuterL n sh a b = FoldOuterL { foldOuterLAccum :: Exp a -> Exp b -> Exp a, foldOuterLInit :: Core.Array sh a,- foldOuterLMap :: Core.Array (n,sh) b+ foldOuterLArray :: Core.Array (n,sh) b } -- FIXME: check correct size of array of initial values foldOuterL ::- (Shape.C sh, Storable sh, MultiValueMemory.C sh,- Shape.C n, Storable n, MultiValueMemory.C n,+ (Shape.C n, Storable n, MultiValueMemory.C n,+ Shape.C sh, Storable sh, MultiValueMemory.C sh, Storable a, MultiValueMemory.C a) => Sym.Hull p (FoldOuterL n sh a b) -> IO (p -> IO (Phys.Array sh a)) foldOuterL = materialize "foldOuterL" (Core.shape . foldOuterLInit) (\(FoldOuterL f arrInit arrData) -> Priv.foldOuterL f arrInit arrData)+++data MapFilter n a b =+ MapFilter {+ mapFilterMap :: Exp a -> Exp b,+ mapFilterPredicate :: Exp a -> Exp Bool,+ mapFilterArray :: Core.Array n a+ }++mapFilter ::+ (Shape.Sequence n,+ Storable n, MultiValueMemory.C n,+ Storable b, MultiValueMemory.C b) =>+ Sym.Hull p (MapFilter n a b) -> IO (p -> IO (Phys.Array n b))+mapFilter =+ materialize "mapFilter"+ (Core.shape . mapFilterArray)+ (\(MapFilter f p arr) shapePtr bufferPtr ->+ flip MultiValueMemory.store shapePtr+ =<< Priv.mapFilter f p arr shapePtr bufferPtr)+++data FilterOuter n sh a =+ FilterOuter {+ filterOuterPredicate :: Core.Array n Bool,+ filterOuterArray :: Core.Array (n,sh) a+ }++-- FIXME: check correct size of row selection array+filterOuter ::+ (Shape.Sequence n, Storable n, MultiValueMemory.C n,+ Shape.C sh, Storable sh, MultiValueMemory.C sh,+ Storable a, MultiValueMemory.C a) =>+ Sym.Hull p (FilterOuter n sh a) -> IO (p -> IO (Phys.Array (n,sh) a))+filterOuter =+ materialize "filterOuter"+ (Core.shape . filterOuterArray)+ (\(FilterOuter p arr) shapePtr bufferPtr ->+ flip MultiValueMemory.store shapePtr+ =<< Priv.filterOuter p arr shapePtr bufferPtr)+++data AddDimension sh n a b =+ AddDimension {+ addDimensionSize :: Exp n,+ addDimensionSelect :: Exp (Shape.Index n) -> Exp a -> Exp b,+ addDimensionArray :: Core.Array sh a+ }++addDimension ::+ (Shape.C sh, Storable sh, MultiValueMemory.C sh,+ Shape.C n, Storable n, MultiValueMemory.C n,+ Storable b, MultiValueMemory.C b) =>+ Sym.Hull p (AddDimension sh n a b) -> IO (p -> IO (Phys.Array (sh,n) b))+addDimension =+ materialize "addDimension"+ (\r -> Expr.zip (Core.shape (addDimensionArray r)) (addDimensionSize r))+ (\(AddDimension n select arr) -> Priv.addDimension n select arr)
src/Data/Array/Knead/Parameterized/Private.hs view
@@ -5,7 +5,7 @@ import qualified Data.Array.Knead.Simple.Symbolic as Core import qualified Data.Array.Knead.Parameter as Param-import qualified Data.Array.Knead.Index.Nested.Shape as Shape+import qualified Data.Array.Knead.Shape.Nested as Shape import qualified Data.Array.Knead.Expression as Expr import Data.Array.Knead.Expression (Exp, ) @@ -113,7 +113,7 @@ MultiValueMemory.C c, Storable c, MultiValue.C a) => (Exp c -> Exp a -> Exp a -> Exp a) -> Param.T p c -> Array p sh a -> Array p z a-fold1All = lift Core.fold1All+fold1All = lift (\p -> Core.fill Shape.scalar . Core.fold1All p) lift :: (Shape.C sh0, Shape.C sh1,@@ -200,6 +200,7 @@ deletePlain () = return () +{-# INLINE combineCreate #-} combineCreate :: Monad m => (p -> m (ctxA, paramA)) -> (p -> m (ctxB, paramB)) ->@@ -209,6 +210,7 @@ (ctxB, paramB) <- createB p return ((ctxA, ctxB), (paramA, paramB)) +{-# INLINE combineDelete #-} combineDelete :: Monad m => (ctxA -> m ()) -> (ctxB -> m ()) -> (ctxA, ctxB) -> m ()
src/Data/Array/Knead/Parameterized/Render.hs view
@@ -4,10 +4,15 @@ -} module Data.Array.Knead.Parameterized.Render ( run,+ MapFilter(..),+ FilterOuter(..), Scatter(..), ScatterMaybe(..),+ MapAccumLSimple(..),+ MapAccumLSequence(..), MapAccumL(..), FoldOuterL(..),+ AddDimension(..), ) where import qualified Data.Array.Knead.Parameterized.PhysicalHull as PhysHullP@@ -16,9 +21,11 @@ import qualified Data.Array.Knead.Simple.Physical as Phys import qualified Data.Array.Knead.Simple.Private as Core import qualified Data.Array.Knead.Parameter as Param-import qualified Data.Array.Knead.Index.Nested.Shape as Shape+import qualified Data.Array.Knead.Shape.Nested as Shape import Data.Array.Knead.Parameterized.PhysicalHull- (Scatter, ScatterMaybe, MapAccumL, FoldOuterL)+ (MapFilter, FilterOuter,+ MapAccumLSimple, MapAccumLSequence, MapAccumL, FoldOuterL,+ Scatter, ScatterMaybe, AddDimension) import Data.Array.Knead.Expression (Exp, ) import qualified LLVM.Extra.Multi.Value.Memory as MultiValueMemory@@ -44,6 +51,22 @@ build = PhysHullP.render instance+ (Shape.Sequence n,+ Storable n, MultiValueMemory.C n,+ Storable b, MultiValueMemory.C b) =>+ C (MapFilter n a b) where+ type Plain (MapFilter n a b) = IO (Phys.Array n b)+ build = PhysHullP.mapFilter++instance+ (Shape.Sequence n, Storable n, MultiValueMemory.C n,+ Shape.C sh, Storable sh, MultiValueMemory.C sh,+ Storable a, MultiValueMemory.C a) =>+ C (FilterOuter n sh a) where+ type Plain (FilterOuter n sh a) = IO (Phys.Array (n,sh) a)+ build = PhysHullP.filterOuter++instance (MultiValueMemory.C sh0, Storable sh0, Shape.C sh0, MultiValueMemory.C sh1, Storable sh1, Shape.C sh1, MultiValueMemory.C a, Storable a) =>@@ -65,18 +88,48 @@ MultiValue.C acc, Storable a, MultiValueMemory.C a, Storable b, MultiValueMemory.C b) =>- C (MapAccumL sh n acc a b) where- type Plain (MapAccumL sh n acc a b) = IO (Phys.Array (sh,n) b)- build = PhysHullP.mapAccumL+ C (MapAccumLSimple sh n acc a b) where+ type Plain (MapAccumLSimple sh n acc a b) = IO (Phys.Array (sh,n) b)+ build = PhysHullP.mapAccumLSimple instance+ (Shape.C n, Storable n, MultiValueMemory.C n,+ MultiValue.C acc,+ Storable final, MultiValueMemory.C final,+ Storable a, MultiValueMemory.C a,+ Storable b, MultiValueMemory.C b) =>+ C (MapAccumLSequence n acc final a b) where+ type Plain (MapAccumLSequence n acc final a b) = IO (final, Phys.Array n b)+ build = PhysHullP.mapAccumLSequence++instance (Shape.C sh, Storable sh, MultiValueMemory.C sh, Shape.C n, Storable n, MultiValueMemory.C n,+ MultiValue.C acc,+ Storable final, MultiValueMemory.C final, Storable a, MultiValueMemory.C a, Storable b, MultiValueMemory.C b) =>+ C (MapAccumL sh n acc final a b) where+ type Plain (MapAccumL sh n acc final a b) =+ IO (Phys.Array sh final, Phys.Array (sh,n) b)+ build = PhysHullP.mapAccumL++instance+ (Shape.C n, Storable n, MultiValueMemory.C n,+ Shape.C sh, Storable sh, MultiValueMemory.C sh,+ Storable a, MultiValueMemory.C a,+ Storable b, MultiValueMemory.C b) => C (FoldOuterL n sh a b) where type Plain (FoldOuterL n sh a b) = IO (Phys.Array sh a) build = PhysHullP.foldOuterL++instance+ (Shape.C sh, Storable sh, MultiValueMemory.C sh,+ Shape.C n, Storable n, MultiValueMemory.C n,+ Storable b, MultiValueMemory.C b) =>+ C (AddDimension sh n a b) where+ type Plain (AddDimension sh n a b) = IO (Phys.Array (sh,n) b)+ build = PhysHullP.addDimension singleton :: Exp a -> Core.Array () a
src/Data/Array/Knead/Parameterized/Slice.hs view
@@ -17,12 +17,12 @@ import qualified Data.Array.Knead.Simple.Slice as Slice import qualified Data.Array.Knead.Simple.Private as Core -import qualified Data.Array.Knead.Index.Linear as Linear-import qualified Data.Array.Knead.Index.Nested.Shape as Shape+import qualified Data.Array.Knead.Shape.Cubic as Linear+import qualified Data.Array.Knead.Shape.Nested as Shape import qualified Data.Array.Knead.Parameter as Param import qualified Data.Array.Knead.Expression as Expr import Data.Array.Knead.Expression (Exp, )-import Data.Array.Knead.Index.Linear ((:.), )+import Data.Array.Knead.Shape.Cubic ((:.), ) import qualified LLVM.Extra.Multi.Value.Memory as MultiValueMemory import qualified LLVM.Extra.Multi.Value as MultiValue
src/Data/Array/Knead/Parameterized/Symbolic.hs view
@@ -22,7 +22,7 @@ import qualified Data.Array.Knead.Simple.Symbolic as Core import Data.Array.Knead.Parameterized.Private (Array, gather, ) -import qualified Data.Array.Knead.Index.Nested.Shape as Shape+import qualified Data.Array.Knead.Shape.Nested as Shape import qualified Data.Array.Knead.Parameter as Param import qualified Data.Array.Knead.Expression as Expr import Data.Array.Knead.Expression (Exp, )
+ src/Data/Array/Knead/Shape/Cubic.hs view
@@ -0,0 +1,581 @@+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+module Data.Array.Knead.Shape.Cubic (+ C(switch),+ switchInt,+ intersect,+ value,+ constant,+ paramWith,+ tunnel,+ flattenIndex,+ peek,+ poke,+ computeSize,++ Struct,+ T(..),+ Z(Z), z,+ (:.)((:.)),+ Shape, shape,+ Index, index,+ cons, (#:.),+ head,+ tail,+ switchR,+ loadMultiValue,+ storeMultiValue,+ ) where++import qualified Data.Array.Knead.Shape.Nested as Shape+import qualified Data.Array.Knead.Shape.Cubic.Int as Index++import qualified Data.Array.Knead.Parameter as Param+import qualified Data.Array.Knead.Expression as Expr+import Data.Array.Knead.Expression (Exp, )++import qualified LLVM.Extra.Multi.Value.Memory as MultiValueMemory+import qualified LLVM.Extra.Multi.Value as MultiValue+import qualified LLVM.Extra.Multi.Iterator as IterMV+import qualified LLVM.Extra.Iterator as Iter+import qualified LLVM.Extra.Arithmetic as A+import qualified LLVM.Extra.Control as C+import LLVM.Extra.Multi.Value (Atom, )++import qualified LLVM.Util.Loop as Loop+import qualified LLVM.Core as LLVM++import qualified Foreign.Storable as St+import Foreign.Storable.FixedArray (sizeOfArray, )+import Foreign.Marshal.Array (advancePtr, )+import Foreign.Ptr (Ptr, castPtr, )++import Control.Monad (liftM2, )++import Prelude hiding (min, head, tail, )+++class C ix where+ switch ::+ f Z ->+ (forall ix0 i. (C ix0, Index.Single i) => f (ix0 :. i)) ->+ f ix++instance C Z where+ switch x _ = x++instance (C ix0, Index.Single i) => C (ix0 :. i) where+ switch _ x = x+++newtype SwitchInt f ix i = SwitchInt {runSwitchInt :: f (ix :. i)}++switchInt ::+ (C ix) =>+ f Z ->+ (forall ix0. (C ix0) => f (ix0 :. Index.Int)) ->+ f ix+switchInt z0 cons0 =+ switch z0+ (runSwitchInt $ Index.switchSingle (SwitchInt cons0))+++newtype Op2 tag sh = Op2 {runOp2 :: Exp (T tag sh) -> Exp (T tag sh) -> Exp (T tag sh)}++intersect :: C sh => Exp (Shape sh) -> Exp (Shape sh) -> Exp (Shape sh)+intersect =+ runOp2 $+ switchInt+ (Op2 $ \z0 _ -> z0)+ (Op2 $+ switchR $ \is i ->+ switchR $ \js j ->+ intersect is js #:. Expr.min i j)+++_value :: (C sh, MultiValue.C sh) => sh -> Exp sh+_value = Expr.lift0 . MultiValue.cons+++newtype MakeValue val tag sh = MakeValue {runMakeValue :: T tag sh -> val (T tag sh)}++value :: (C sh, Expr.Value val) => T tag sh -> val (T tag sh)+value =+ runMakeValue $+ switchInt+ (MakeValue $ \(Cons Z) -> z)+ (MakeValue $ \(Cons (t:.h)) ->+ value (Cons t) #:. Expr.lift0 (MultiValue.cons h))++paramWith ::+ (C sh, Expr.Value val) =>+ Param.T p (T tag sh) ->+ (forall parameters.+ (St.Storable parameters,+ MultiValueMemory.C parameters) =>+ (p -> parameters) ->+ (MultiValue.T parameters -> val (T tag sh)) ->+ a) ->+ a+paramWith p f =+ case tunnel p of+ Param.Tunnel get val -> f get (Expr.lift0 . val)++tunnel :: (C sh) => Param.T p (T tag sh) -> Param.Tunnel p (T tag sh)+tunnel p =+ case structFieldsPropF p of+ StructFieldsProp -> Param.tunnel value p+++data StructFieldsProp sh = LLVM.StructFields (Struct sh) => StructFieldsProp++_structFieldsProp :: (C sh) => f sh -> StructFieldsProp sh+_structFieldsProp _p = structFieldsRec++structFieldsPropF :: (C sh) => f (g sh) -> StructFieldsProp sh+structFieldsPropF _p = structFieldsRec++withStructFieldsPropFF ::+ (C sh) => (StructFieldsProp sh -> f (g (h sh))) -> f (g (h sh))+withStructFieldsPropFF f = f structFieldsRec++structFieldsRec :: (C sh) => StructFieldsProp sh+structFieldsRec =+ switchInt+ StructFieldsProp+ (succStructFieldsProp structFieldsRec)++succStructFieldsProp ::+ StructFieldsProp sh -> StructFieldsProp (sh:.Index.Int)+succStructFieldsProp StructFieldsProp = StructFieldsProp+++data Z = Z+ deriving (Eq, Ord, Read, Show)+++infixl 3 :., #:.++data tail :. head = !tail :. !head+ deriving (Eq, Ord, Read, Show)+++newtype T tag sh = Cons {decons :: sh}++data ShapeTag+data IndexTag++type Shape = T ShapeTag+type Index = T IndexTag++shape :: sh -> Shape sh+shape = Cons++index :: ix -> Index ix+index = Cons+++(#:.) :: (Expr.Value val) => val (T tag sh) -> val i -> val (T tag (sh:.i))+(#:.) = cons++cons :: (Expr.Value val) => val (T tag sh) -> val i -> val (T tag (sh:.i))+cons =+ Expr.lift2 $+ \(MultiValue.Cons t) (MultiValue.Cons h) ->+ MultiValue.Cons (t,h)++z :: (Expr.Value val) => val (T tag Z)+z = Expr.lift0 $ MultiValue.Cons ()++head :: (Expr.Value val) => val (T tag (sh:.i)) -> val i+head = Expr.lift1 $ \(MultiValue.Cons (_t,h)) -> MultiValue.Cons h++tail :: (Expr.Value val) => val (T tag (sh:.i)) -> val (T tag sh)+tail = Expr.lift1 $ \(MultiValue.Cons (t,_h)) -> MultiValue.Cons t++switchR ::+ Expr.Value val =>+ (val (T tag sh) -> val i -> a) -> val (T tag (sh :. i)) -> a+switchR f ix = f (tail ix) (head ix)+++instance (tag ~ ShapeTag, sh ~ Z) => Shape.Scalar (T tag sh) where+ scalar = Expr.lift0 $ MultiValue.Cons ()+ zeroIndex _ = Expr.lift0 $ MultiValue.Cons ()+++type family PatternTuple pattern+type family Decomposed (f :: * -> *) tag pattern++type instance PatternTuple (sh:.s) =+ PatternTuple sh :. MultiValue.PatternTuple s++type instance Decomposed f tag (sh:.s) =+ Decomposed f tag sh :. MultiValue.Decomposed f s++type instance PatternTuple (Atom sh) = sh++type instance Decomposed f tag (Atom sh) = f (T tag sh)+++class+ (Expr.Composed (Decomposed Exp tag pattern) ~ T tag (PatternTuple pattern)) =>+ Decompose tag pattern where+ decompose ::+ T tag pattern -> Exp (T tag (PatternTuple pattern)) ->+ Decomposed Exp tag pattern++instance Decompose tag (Atom sh) where+ decompose (Cons _atom) x = x++instance (Decompose tag sh, Expr.Decompose s) => Decompose tag (sh :. s) where+ decompose (Cons (psh:.ps)) x =+ decompose (Cons psh) (tail x) :. Expr.decompose ps (head x)+++type instance MultiValue.PatternTuple (T tag sh) = T tag (PatternTuple sh)++type instance MultiValue.Decomposed f (T tag sh) = Decomposed f tag sh+++type family Unwrap sh+type instance Unwrap (T tag sh) = sh++type family Tag sh+type instance Tag (T tag sh) = tag++instance+ (Expr.Compose sh,+ Expr.Composed sh ~ T (Tag (Expr.Composed sh)) (Unwrap (Expr.Composed sh)),+ Expr.Compose s) =>+ Expr.Compose (sh :. s) where+ type Composed (sh :. s) =+ T (Tag (Expr.Composed sh))+ (Unwrap (Expr.Composed sh) :. Expr.Composed s)+ compose (sh :. s) = cons (Expr.compose sh) (Expr.compose s)++instance (Decompose tag sh) => Expr.Decompose (T tag sh) where+ decompose = decompose++++instance (C sh) => St.Storable (T tag sh) where+ sizeOf (Cons sh) = sizeOfArray (rank sh) (0::Shape.Size)+ alignment (Cons _sh) = St.alignment (0::Shape.Size)+ poke ptr = poke (castPtr ptr) . decons+ peek = fmap Cons . peek . castPtr+++type family Repr (f :: * -> *) sh+type instance Repr f Z = ()+type instance Repr f (tail :. head) = (Repr f tail, MultiValue.Repr f head)++instance (C sh) => MultiValue.C (T tag sh) where+ type Repr f (T tag sh) = Repr f sh+ cons = value+ undef = constant $ MultiValue.undef+ zero = constant $ MultiValue.zero+ addPhis = addPhis+ phis = phis++instance (tag ~ ShapeTag, C sh) => Shape.C (T tag sh) where+ type Index (T tag sh) = Index sh+ size = fromIntegral . size . decons+ sizeCode = computeSize+ intersectCode = Expr.unliftM2 intersect+ flattenIndexRec sh ix =+ -- a joint implementation would not be more efficient+ liftM2 (,)+ (computeSize sh)+ (flattenIndex sh ix)+ iterator = iterator+ loop = loop+++type family Struct sh+type instance Struct Z = ()+type instance Struct (sh :. Index.Int) = (Shape.Size, Struct sh)++instance+ (C sh, LLVM.StructFields (Struct sh)) =>+ MultiValueMemory.C (T tag sh) where+ type Struct (T tag sh) = LLVM.Struct (Struct sh)+ load = loadMultiValue+ store = storeMultiValue++loadMultiValue ::+ (C sh) =>+ LLVM.Value (Ptr (LLVM.Struct (Struct sh))) ->+ LLVM.CodeGenFunction r (MultiValue.T (T tag sh))+loadMultiValue ptr =+ withStructFieldsPropFF $ \StructFieldsProp ->+ load =<< castPtrValue ptr++storeMultiValue ::+ (C sh) =>+ MultiValue.T (T tag sh) ->+ LLVM.Value (Ptr (LLVM.Struct (Struct sh))) -> LLVM.CodeGenFunction r ()+storeMultiValue x ptr =+ case structFieldsPropF x of+ StructFieldsProp -> store x =<< castPtrValue ptr+++newtype FlattenIndex r sh =+ FlattenIndex {+ runFlattenIndex ::+ MultiValue.T (Shape sh) -> MultiValue.T (Index sh) ->+ LLVM.CodeGenFunction r (LLVM.Value Shape.Size)+ }++flattenIndex ::+ (C sh) =>+ MultiValue.T (Shape sh) -> MultiValue.T (Index sh) ->+ LLVM.CodeGenFunction r (LLVM.Value Shape.Size)+flattenIndex =+ runFlattenIndex $+ switchInt+ (FlattenIndex $ \_zerosh _zeroix -> return A.zero)+ (FlattenIndex $+ switchR $ \sh (MultiValue.Cons s) ->+ switchR $ \ix (MultiValue.Cons i) ->+ A.add i =<< A.mul s =<< flattenIndex sh ix)+++newtype Rank sh = Rank {runRank :: sh -> Int}++rank :: (C sh) => sh -> Int+rank =+ runRank $+ switch+ (Rank $ const 0)+ (Rank $ succ . rank . (\(sh :. _s) -> sh))+++newtype Peek sh = Peek {runPeek :: Ptr Shape.Size -> IO sh}++peek :: (C sh) => Ptr Shape.Size -> IO sh+peek =+ runPeek $+ switchInt+ (Peek $ const $ return Z)+ (Peek $ \ptr -> do+ h <- St.peek ptr+ t <- peek $ advancePtr ptr 1+ return (t :. Index.Int h))+++newtype Poke sh = Poke {runPoke :: Ptr Shape.Size -> sh -> IO ()}++poke :: (C sh) => Ptr Shape.Size -> sh -> IO ()+poke =+ runPoke $+ switchInt+ (Poke $ const $ const $ return ())+ (Poke $ \ptr (sh :. Index.Int i) -> do+ St.poke ptr i+ poke (advancePtr ptr 1) sh)+++castPtrValue ::+ (LLVM.StructFields sh) =>+ LLVM.Value (Ptr (LLVM.Struct sh)) ->+ LLVM.CodeGenFunction r (LLVM.Value (Ptr Shape.Size))+castPtrValue = LLVM.bitcast++newtype Load r tag sh =+ Load {+ runLoad ::+ LLVM.Value (Ptr Shape.Size) ->+ LLVM.CodeGenFunction r (MultiValue.T (T tag sh))+ }++load ::+ (C sh) =>+ LLVM.Value (Ptr Shape.Size) ->+ LLVM.CodeGenFunction r (MultiValue.T (T tag sh))+load =+ runLoad $+ switchInt+ (Load $ const $ return z)+ (Load $ \ptr -> do+ h <- LLVM.load ptr+ t <- load =<< A.advanceArrayElementPtr ptr+ return (t #:. MultiValue.Cons h))+++newtype Store r tag sh =+ Store {+ runStore ::+ MultiValue.T (T tag sh) ->+ LLVM.Value (Ptr Shape.Size) ->+ LLVM.CodeGenFunction r ()+ }++store ::+ (C sh) =>+ MultiValue.T (T tag sh) ->+ LLVM.Value (Ptr Shape.Size) ->+ LLVM.CodeGenFunction r ()+store =+ runStore $+ switchInt+ (Store $ \_z _ptr -> return ())+ (Store $ switchR $ \sh (MultiValue.Cons k) ptr -> do+ LLVM.store k ptr+ store sh =<< A.advanceArrayElementPtr ptr)+++newtype Size sh =+ Size {+ runSize :: sh -> Shape.Size+ }++size :: (C sh) => sh -> Shape.Size+size =+ runSize $+ switchInt+ (Size $ \_z -> 1)+ (Size $ \(sh :. Index.Int k) -> k * size sh)+++newtype ComputeSize r sh =+ ComputeSize {+ runComputeSize ::+ MultiValue.T (Shape sh) ->+ LLVM.CodeGenFunction r (LLVM.Value Shape.Size)+ }++computeSize ::+ (C sh) =>+ MultiValue.T (Shape sh) ->+ LLVM.CodeGenFunction r (LLVM.Value Shape.Size)+computeSize =+ runComputeSize $+ switchInt+ (ComputeSize $ \_z -> return A.one)+ (ComputeSize $ switchR $ \sh (MultiValue.Cons k) ->+ A.mul k =<< computeSize sh)+++newtype+ Constant val tag sh =+ Constant {getConstant :: val Index.Int -> val (T tag sh)}++constant :: (C sh, Expr.Value val) => val Index.Int -> val (T tag sh)+constant =+ getConstant $+ switchInt+ (Constant $ const z)+ (Constant $ \x -> constant x #:. x)+++newtype AddPhis r tag sh =+ AddPhis {+ runAddPhis ::+ LLVM.BasicBlock ->+ MultiValue.T (T tag sh) ->+ MultiValue.T (T tag sh) ->+ LLVM.CodeGenFunction r ()+ }++addPhis ::+ (C sh) =>+ LLVM.BasicBlock ->+ MultiValue.T (T tag sh) ->+ MultiValue.T (T tag sh) ->+ LLVM.CodeGenFunction r ()+addPhis =+ runAddPhis $+ switchInt+ (AddPhis $ \_ _ _ -> return ())+ (AddPhis $ \bb ->+ switchR $ \hx tx ->+ switchR $ \hy ty ->+ MultiValue.addPhis bb tx ty >>+ addPhis bb hx hy)+++newtype Phis r tag sh =+ Phis {+ runPhis ::+ LLVM.BasicBlock ->+ MultiValue.T (T tag sh) ->+ LLVM.CodeGenFunction r (MultiValue.T (T tag sh))+ }++phis ::+ (C sh) =>+ LLVM.BasicBlock ->+ MultiValue.T (T tag sh) ->+ LLVM.CodeGenFunction r (MultiValue.T (T tag sh))+phis =+ runPhis $+ switchInt+ (Phis $ \_ -> return)+ (Phis $ \bb ->+ switchR $ \h t ->+ liftM2 (#:.)+ (phis bb h)+ (MultiValue.phis bb t))+++newtype Iterator r sh =+ Iterator {+ runIterator ::+ MultiValue.T (Shape sh) -> Iter.T r (MultiValue.T (Index sh))+ }++iterator ::+ (C sh) =>+ MultiValue.T (Shape sh) -> Iter.T r (MultiValue.T (Index sh))+iterator =+ runIterator $+ switchInt+ (Iterator $ \ _z -> Iter.empty)+ (Iterator $ switchR $ \sh n ->+ fmap (\(ix,i) -> ix#:.i) $+ Iter.cartesian+ (iterator sh)+ (IterMV.takeWhile (MultiValue.cmp LLVM.CmpGT n) $+ Iter.iterate MultiValue.inc MultiValue.zero))+++newtype Loop r state sh =+ Loop {+ runLoop ::+ (MultiValue.T (Index sh) ->+ state ->+ LLVM.CodeGenFunction r state) ->+ MultiValue.T (Shape sh) ->+ state ->+ LLVM.CodeGenFunction r state+ }++loop ::+ (C sh, Loop.Phi state) =>+ (MultiValue.T (Index sh) ->+ state ->+ LLVM.CodeGenFunction r state) ->+ MultiValue.T (Shape sh) ->+ state ->+ LLVM.CodeGenFunction r state+loop =+ runLoop $+ switchInt+ (Loop $ \code _z -> code z)+ (Loop $ \code -> switchR $ \sh (MultiValue.Cons n) ->+ loop+ (\ix ptrStart ->+ fmap fst $+ C.fixedLengthLoop n (ptrStart, A.zero) $ \(ptr, k) ->+ liftM2 (,)+ (code (ix #:. MultiValue.Cons k) ptr)+ (A.inc k))+ sh)
+ src/Data/Array/Knead/Shape/Cubic/Int.hs view
@@ -0,0 +1,59 @@+{-# LANGUAGE TypeFamilies #-}+module Data.Array.Knead.Shape.Cubic.Int (+ Single(..),+ Int(Int), cons, decons,+ ) where++import qualified Data.Array.Knead.Expression as Expr++import qualified LLVM.Extra.Multi.Value as MultiValue+import qualified LLVM.Extra.Arithmetic as A++import Data.Word (Word64, )++import Prelude hiding (Int, head, tail, )+++newtype Int = Int Word64++cons :: (Expr.Value val) => val Word64 -> val Int+cons = Expr.lift1 $ \(MultiValue.Cons x) -> MultiValue.Cons x++decons :: (Expr.Value val) => val Int -> val Word64+decons = Expr.lift1 $ \(MultiValue.Cons x) -> MultiValue.Cons x+++class Single ix where+ switchSingle :: f Int -> f ix++instance Single Int where+ switchSingle x = x+++instance MultiValue.C Int where+ type Repr f Int = f Word64+ cons (Int x) = MultiValue.consPrimitive x+ undef = MultiValue.undefPrimitive+ zero = MultiValue.zeroPrimitive+ phis = MultiValue.phisPrimitive+ addPhis = MultiValue.addPhisPrimitive++instance MultiValue.Additive Int where+ add = MultiValue.liftM2 A.add+ sub = MultiValue.liftM2 A.sub+ neg = MultiValue.liftM A.neg++instance MultiValue.PseudoRing Int where+ mul = MultiValue.liftM2 A.mul++instance MultiValue.Real Int where+ min = MultiValue.liftM2 A.min+ max = MultiValue.liftM2 A.max+ abs = MultiValue.liftM A.abs+ signum = MultiValue.liftM A.signum++instance MultiValue.IntegerConstant Int where+ fromInteger' = cons . A.fromInteger'++instance MultiValue.Comparison Int where+ cmp mode = MultiValue.liftM2 $ A.cmp mode
+ src/Data/Array/Knead/Shape/Nested.hs view
@@ -0,0 +1,539 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE FlexibleContexts #-}+module Data.Array.Knead.Shape.Nested (+ C(..),+ Size,+ value,+ paramWith,+ load,+ intersect,+ flattenIndex,++ Range(..),+ Shifted(..),++ Scalar(..),+ Sequence(..),+ ) where++import qualified Data.Array.Knead.Expression as Expr+import qualified Data.Array.Knead.Parameter as Param+import Data.Array.Knead.Expression (Exp, )++import qualified LLVM.Extra.Multi.Value.Memory as MultiMem+import qualified LLVM.Extra.Multi.Value as MultiValue+import qualified LLVM.Extra.Multi.Iterator as IterMV+import qualified LLVM.Extra.Iterator as Iter+import qualified LLVM.Extra.Arithmetic as A+import LLVM.Extra.Multi.Value (atom)++import qualified LLVM.Util.Loop as Loop+import qualified LLVM.Core as LLVM++import qualified Type.Data.Num.Decimal as TypeNum++import Foreign.Storable+ (Storable, sizeOf, alignment, poke, peek, pokeElemOff, peekElemOff)+import Foreign.Ptr (Ptr, castPtr)++import Data.Word (Word8, Word16, Word32, Word64)+import Data.Int (Int8, Int16, Int32, Int64)++import qualified Control.Monad.HT as Monad+import Control.Applicative ((<$>))+++type Size = Word64++value :: (C sh, Expr.Value val) => sh -> val sh+value = Expr.lift0 . MultiValue.cons++paramWith ::+ (Storable b, MultiMem.C b, Expr.Value val) =>+ Param.T p b ->+ (forall parameters.+ (Storable parameters, MultiMem.C parameters) =>+ (p -> parameters) ->+ (MultiValue.T parameters -> val b) ->+ a) ->+ a+paramWith p f =+ Param.withMulti p (\get val -> f get (Expr.lift0 . val))++load ::+ (MultiMem.C sh) =>+ f sh -> LLVM.Value (Ptr (MultiMem.Struct sh)) ->+ LLVM.CodeGenFunction r (MultiValue.T sh)+load _ = MultiMem.load++intersect :: (C sh) => Exp sh -> Exp sh -> Exp sh+intersect = Expr.liftM2 intersectCode++flattenIndex ::+ (C sh) =>+ MultiValue.T sh -> MultiValue.T (Index sh) ->+ LLVM.CodeGenFunction r (LLVM.Value Size)+flattenIndex sh ix =+ fmap snd $ flattenIndexRec sh ix++class (MultiValue.C sh, MultiValue.C (Index sh)) => C sh where+ type Index sh :: *+ {-+ It would be better to restrict zipWith to matching shapes+ and turn shape intersection into a bound check.+ -}+ intersectCode ::+ MultiValue.T sh -> MultiValue.T sh ->+ LLVM.CodeGenFunction r (MultiValue.T sh)+ sizeCode ::+ MultiValue.T sh ->+ LLVM.CodeGenFunction r (LLVM.Value Size)+ size :: sh -> Int+ {- |+ Result is @(size, flattenedIndex)@.+ @size@ must equal the result of 'sizeCode'.+ We use this for sharing intermediate results.+ -}+ flattenIndexRec ::+ MultiValue.T sh -> MultiValue.T (Index sh) ->+ LLVM.CodeGenFunction r (LLVM.Value Size, LLVM.Value Size)+ iterator :: (Index sh ~ ix) => MultiValue.T sh -> Iter.T r (MultiValue.T ix)+ loop ::+ (Index sh ~ ix, MultiValue.C ix, Loop.Phi state) =>+ (MultiValue.T ix -> state -> LLVM.CodeGenFunction r state) ->+ MultiValue.T sh -> state -> LLVM.CodeGenFunction r state+ loop f sh = Iter.mapState_ f (iterator sh)+++instance C () where+ type Index () = ()+ intersectCode _ _ = return $ MultiValue.cons ()+ sizeCode _ = return A.one+ size _ = 1+ flattenIndexRec _ _ = return (A.one, A.zero)+ iterator = Iter.singleton+ loop = id+++class C sh => Scalar sh where+ scalar :: (Expr.Value val) => val sh+ zeroIndex :: (Expr.Value val) => f sh -> val (Index sh)++instance Scalar () where+ scalar = Expr.lift0 $ MultiValue.Cons ()+ zeroIndex _ = Expr.lift0 $ MultiValue.Cons ()+++class+ (C sh,+ MultiValue.IntegerConstant (Index sh),+ MultiValue.Additive (Index sh)) =>+ Sequence sh where+ sequenceShapeFromIndex ::+ MultiValue.T (Index sh) -> LLVM.CodeGenFunction r (MultiValue.T sh)+++iteratorPrimitive ::+ (MultiValue.Repr LLVM.Value j ~ LLVM.Value j,+ Num j, LLVM.IsConst j, LLVM.IsInteger j,+ LLVM.CmpRet j, LLVM.CmpResult j ~ Bool,+ MultiValue.Additive j, MultiValue.IntegerConstant j) =>+ MultiValue.T j -> Iter.T r (MultiValue.T j)+iteratorPrimitive (MultiValue.Cons n) = iteratorStart n MultiValue.zero++iteratorStart ::+ (Num j, LLVM.IsConst j, LLVM.IsInteger j,+ LLVM.CmpRet j, LLVM.CmpResult j ~ Bool,+ MultiValue.Additive i, MultiValue.IntegerConstant i) =>+ LLVM.Value j -> MultiValue.T i -> Iter.T r (MultiValue.T i)+iteratorStart n start = Iter.take n $ Iter.iterate MultiValue.inc start+++instance C Word32 where+ type Index Word32 = Word32+ intersectCode = MultiValue.min+ sizeCode (MultiValue.Cons n) = LLVM.ext n+ size = fromIntegral+ flattenIndexRec (MultiValue.Cons n) (MultiValue.Cons i) =+ Monad.lift2 (,) (LLVM.ext n) (LLVM.ext i)+ iterator = iteratorPrimitive++instance Sequence Word32 where+ sequenceShapeFromIndex = return++instance C Word64 where+ type Index Word64 = Word64+ intersectCode = MultiValue.min+ sizeCode (MultiValue.Cons n) = return n+ size = fromIntegral+ flattenIndexRec (MultiValue.Cons n) (MultiValue.Cons i) = return (n, i)+ iterator = iteratorPrimitive++instance Sequence Word64 where+ sequenceShapeFromIndex = return+++{- |+Array dimensions and indexes cannot be negative,+but computations in indices may temporarily yield negative values+or we want to add negative values to indices.++Maybe we should better have type Index Word64 = Int64?+-}+unsigned8 :: LLVM.Value Int8 -> LLVM.CodeGenFunction r (LLVM.Value Word8)+unsigned8 = LLVM.bitcast++instance C Int8 where+ type Index Int8 = Int8+ intersectCode = MultiValue.min+ sizeCode (MultiValue.Cons n) = LLVM.ext =<< unsigned8 n+ size = fromIntegral+ flattenIndexRec (MultiValue.Cons n) (MultiValue.Cons i) =+ Monad.lift2 (,) (LLVM.ext =<< unsigned8 n) (LLVM.ext =<< unsigned8 i)+ iterator = iteratorPrimitive++instance Sequence Int8 where+ sequenceShapeFromIndex = return++unsigned16 :: LLVM.Value Int16 -> LLVM.CodeGenFunction r (LLVM.Value Word16)+unsigned16 = LLVM.bitcast++instance C Int16 where+ type Index Int16 = Int16+ intersectCode = MultiValue.min+ sizeCode (MultiValue.Cons n) = LLVM.ext =<< unsigned16 n+ size = fromIntegral+ flattenIndexRec (MultiValue.Cons n) (MultiValue.Cons i) =+ Monad.lift2 (,) (LLVM.ext =<< unsigned16 n) (LLVM.ext =<< unsigned16 i)+ iterator = iteratorPrimitive++instance Sequence Int16 where+ sequenceShapeFromIndex = return++instance C Int32 where+ type Index Int32 = Int32+ intersectCode = MultiValue.min+ sizeCode (MultiValue.Cons n) = LLVM.zext n+ size = fromIntegral+ flattenIndexRec (MultiValue.Cons n) (MultiValue.Cons i) =+ Monad.lift2 (,) (LLVM.zext n) (LLVM.zext i)+ iterator = iteratorPrimitive++instance Sequence Int32 where+ sequenceShapeFromIndex = return++instance C Int64 where+ type Index Int64 = Int64+ intersectCode = MultiValue.min+ sizeCode (MultiValue.Cons n) = LLVM.bitcast n+ size = fromIntegral+ flattenIndexRec (MultiValue.Cons n) (MultiValue.Cons i) =+ Monad.lift2 (,) (LLVM.bitcast n) (LLVM.bitcast i)+ iterator = iteratorPrimitive++instance Sequence Int64 where+ sequenceShapeFromIndex = return+++{- |+'Range' denotes an inclusive range like+those of the Haskell 98 standard @Array@ type from the @array@ package.+E.g. the shape type @(Range Int32, Range Int64)@+is equivalent to the ix type @(Int32, Int64)@ for @Array@s.+-}+data Range n = Range n n++singletonRange :: n -> Range n+singletonRange n = Range n n+++{-# INLINE castToElemPtr #-}+castToElemPtr :: Ptr (f a) -> Ptr a+castToElemPtr = castPtr++-- cf. sample-frame:Stereo+instance Storable n => Storable (Range n) where+ {-# INLINE sizeOf #-}+ {-# INLINE alignment #-}+ {-# INLINE peek #-}+ {-# INLINE poke #-}+ sizeOf ~(Range l r) = sizeOf l + mod (- sizeOf l) (alignment r) + sizeOf r+ alignment ~(Range l _) = alignment l+ poke p (Range l r) =+ let q = castToElemPtr p+ in poke q l >> pokeElemOff q 1 r+ peek p =+ let q = castToElemPtr p+ in Monad.lift2 Range (peek q) (peekElemOff q 1)+++class+ (MultiValue.Additive n, MultiValue.Real n, MultiValue.IntegerConstant n) =>+ ToSize n where+ toSize :: MultiValue.T n -> LLVM.CodeGenFunction r (LLVM.Value Size)++instance ToSize Word32 where toSize (MultiValue.Cons n) = LLVM.ext n+instance ToSize Word64 where toSize (MultiValue.Cons n) = return n+instance ToSize Int32 where toSize (MultiValue.Cons n) = LLVM.zext n+instance ToSize Int64 where toSize (MultiValue.Cons n) = LLVM.bitcast n++rangeSize ::+ (ToSize n) =>+ Range (MultiValue.T n) -> LLVM.CodeGenFunction r (LLVM.Value Size)+rangeSize (Range from to) =+ toSize =<< MultiValue.inc =<< MultiValue.sub to from++unzipRange :: MultiValue.T (Range n) -> Range (MultiValue.T n)+unzipRange (MultiValue.Cons (Range from to)) =+ Range (MultiValue.Cons from) (MultiValue.Cons to)++zipRange :: MultiValue.T n -> MultiValue.T n -> MultiValue.T (Range n)+zipRange (MultiValue.Cons from) (MultiValue.Cons to) =+ MultiValue.Cons (Range from to)++instance (MultiValue.C n) => MultiValue.C (Range n) where+ type Repr f (Range n) = Range (MultiValue.Repr f n)+ cons (Range from to) = zipRange (MultiValue.cons from) (MultiValue.cons to)+ undef = MultiValue.compose $ singletonRange MultiValue.undef+ zero = MultiValue.compose $ singletonRange MultiValue.zero+ phis bb a =+ case unzipRange a of+ Range a0 a1 ->+ Monad.lift2 zipRange (MultiValue.phis bb a0) (MultiValue.phis bb a1)+ addPhis bb a b =+ case (unzipRange a, unzipRange b) of+ (Range a0 a1, Range b0 b1) ->+ MultiValue.addPhis bb a0 b0 >>+ MultiValue.addPhis bb a1 b1++type instance+ MultiValue.Decomposed f (Range pn) =+ Range (MultiValue.Decomposed f pn)+type instance+ MultiValue.PatternTuple (Range pn) =+ Range (MultiValue.PatternTuple pn)++instance (MultiValue.Compose n) => MultiValue.Compose (Range n) where+ type Composed (Range n) = Range (MultiValue.Composed n)+ compose (Range from to) =+ zipRange (MultiValue.compose from) (MultiValue.compose to)++instance (MultiValue.Decompose pn) => MultiValue.Decompose (Range pn) where+ decompose (Range pfrom pto) rng =+ case unzipRange rng of+ Range from to ->+ Range+ (MultiValue.decompose pfrom from)+ (MultiValue.decompose pto to)++instance (MultiMem.C n) => MultiMem.C (Range n) where+ type Struct (Range n) = PairStruct n+ decompose = fmap (uncurry zipRange) . decomposeGen+ compose x = case unzipRange x of Range n m -> composeGen n m++instance (Integral n, ToSize n, MultiValue.Comparison n) => C (Range n) where+ type Index (Range n) = n+ intersectCode =+ MultiValue.modifyF2 (singletonRange atom) (singletonRange atom) $+ \(Range fromN toN) (Range fromM toM) ->+ Monad.lift2 Range (MultiValue.max fromN fromM) (MultiValue.min toN toM)+ sizeCode = rangeSize . unzipRange+ size (Range from to) = fromIntegral $ to-from+1+ flattenIndexRec rngValue i =+ case unzipRange rngValue of+ rng@(Range from _to) ->+ Monad.lift2 (,) (rangeSize rng) (toSize =<< MultiValue.sub i from)+ iterator rngValue =+ case MultiValue.decompose (singletonRange atom) rngValue of+ Range from to ->+ IterMV.takeWhile (MultiValue.cmp LLVM.CmpGE to) $+ Iter.iterate MultiValue.inc from+++{- |+'Shifted' denotes a range defined by the start index and the length.+-}+data Shifted n = Shifted {shiftedOffset, shiftedSize :: n}++singletonShifted :: n -> Shifted n+singletonShifted n = Shifted n n+++-- cf. sample-frame:Stereo+instance Storable n => Storable (Shifted n) where+ {-# INLINE sizeOf #-}+ {-# INLINE alignment #-}+ {-# INLINE peek #-}+ {-# INLINE poke #-}+ sizeOf ~(Shifted l n) = sizeOf l + mod (- sizeOf l) (alignment n) + sizeOf n+ alignment ~(Shifted l _) = alignment l+ poke p (Shifted l n) =+ let q = castToElemPtr p+ in poke q l >> pokeElemOff q 1 n+ peek p =+ let q = castToElemPtr p+ in Monad.lift2 Shifted (peek q) (peekElemOff q 1)+++unzipShifted :: MultiValue.T (Shifted n) -> Shifted (MultiValue.T n)+unzipShifted (MultiValue.Cons (Shifted from to)) =+ Shifted (MultiValue.Cons from) (MultiValue.Cons to)++zipShifted :: MultiValue.T n -> MultiValue.T n -> MultiValue.T (Shifted n)+zipShifted (MultiValue.Cons from) (MultiValue.Cons to) =+ MultiValue.Cons (Shifted from to)++instance (MultiValue.C n) => MultiValue.C (Shifted n) where+ type Repr f (Shifted n) = Shifted (MultiValue.Repr f n)+ cons (Shifted offset len) =+ zipShifted (MultiValue.cons offset) (MultiValue.cons len)+ undef = MultiValue.compose $ singletonShifted MultiValue.undef+ zero = MultiValue.compose $ singletonShifted MultiValue.zero+ phis bb a =+ case unzipShifted a of+ Shifted a0 a1 ->+ Monad.lift2 zipShifted+ (MultiValue.phis bb a0) (MultiValue.phis bb a1)+ addPhis bb a b =+ case (unzipShifted a, unzipShifted b) of+ (Shifted a0 a1, Shifted b0 b1) ->+ MultiValue.addPhis bb a0 b0 >>+ MultiValue.addPhis bb a1 b1++type instance+ MultiValue.Decomposed f (Shifted pn) =+ Shifted (MultiValue.Decomposed f pn)+type instance+ MultiValue.PatternTuple (Shifted pn) =+ Shifted (MultiValue.PatternTuple pn)++instance (MultiValue.Compose n) => MultiValue.Compose (Shifted n) where+ type Composed (Shifted n) = Shifted (MultiValue.Composed n)+ compose (Shifted offset len) =+ zipShifted (MultiValue.compose offset) (MultiValue.compose len)++instance (MultiValue.Decompose pn) => MultiValue.Decompose (Shifted pn) where+ decompose (Shifted poffset plen) rng =+ case unzipShifted rng of+ Shifted offset len ->+ Shifted+ (MultiValue.decompose poffset offset)+ (MultiValue.decompose plen len)++instance (MultiMem.C n) => MultiMem.C (Shifted n) where+ type Struct (Shifted n) = PairStruct n+ decompose = fmap (uncurry zipShifted) . decomposeGen+ compose x = case unzipShifted x of Shifted n m -> composeGen n m++type PairStruct n = LLVM.Struct (MultiMem.Struct n, (MultiMem.Struct n, ()))++decomposeGen ::+ (MultiMem.C n) =>+ LLVM.Value (PairStruct n) ->+ LLVM.CodeGenFunction r (MultiValue.T n, MultiValue.T n)+decomposeGen nm =+ Monad.lift2 (,)+ (MultiMem.decompose =<< LLVM.extractvalue nm TypeNum.d0)+ (MultiMem.decompose =<< LLVM.extractvalue nm TypeNum.d1)++composeGen ::+ (MultiMem.C n) =>+ MultiValue.T n -> MultiValue.T n ->+ LLVM.CodeGenFunction r (LLVM.Value (PairStruct n))+composeGen n m = do+ sn <- MultiMem.compose n+ sm <- MultiMem.compose m+ rn <- LLVM.insertvalue (LLVM.value LLVM.undef) sn TypeNum.d0+ LLVM.insertvalue rn sm TypeNum.d1+++instance (Integral n, ToSize n, MultiValue.Comparison n) => C (Shifted n) where+ type Index (Shifted n) = n+ intersectCode =+ MultiValue.modifyF2 (singletonShifted atom) (singletonShifted atom) $+ \(Shifted offsetN lenN) (Shifted offsetM lenM) -> do+ offset <- MultiValue.max offsetN offsetM+ endN <- MultiValue.add offsetN lenN+ endM <- MultiValue.add offsetM lenM+ end <- MultiValue.min endN endM+ Shifted offset <$> MultiValue.sub end offset+ sizeCode = toSize . shiftedSize . unzipShifted+ size (Shifted _offset len) = fromIntegral len+ flattenIndexRec shapeValue i =+ case unzipShifted shapeValue of+ Shifted offset len ->+ Monad.lift2 (,) (toSize len) (toSize =<< MultiValue.sub i offset)+ iterator rngValue =+ case MultiValue.decompose (singletonShifted atom) rngValue of+ Shifted from len ->+ IterMV.take len $ Iter.iterate MultiValue.inc from++++instance (C n, C m) => C (n,m) where+ type Index (n,m) = (Index n, Index m)+ intersectCode a b =+ case (MultiValue.unzip a, MultiValue.unzip b) of+ ((an,am), (bn,bm)) ->+ Monad.lift2 MultiValue.zip+ (intersectCode an bn)+ (intersectCode am bm)+ sizeCode nm =+ case MultiValue.unzip nm of+ (n,m) -> Monad.liftJoin2 A.mul (sizeCode n) (sizeCode m)+ size (n,m) = size n * size m+ flattenIndexRec nm ij =+ case (MultiValue.unzip nm, MultiValue.unzip ij) of+ ((n,m), (i,j)) -> do+ (ns, il) <- flattenIndexRec n i+ (ms, jl) <- flattenIndexRec m j+ Monad.lift2 (,)+ (A.mul ns ms)+ (A.add jl =<< A.mul ms il)+ iterator nm =+ case MultiValue.unzip nm of+ (n,m) ->+ uncurry MultiValue.zip <$>+ Iter.cartesian (iterator n) (iterator m)+ loop code nm =+ case MultiValue.unzip nm of+ (n,m) -> loop (\i -> loop (\j -> code (MultiValue.zip i j)) m) n++instance (C n, C m, C l) => C (n,m,l) where+ type Index (n,m,l) = (Index n, Index m, Index l)+ intersectCode a b =+ case (MultiValue.unzip3 a, MultiValue.unzip3 b) of+ ((ai,aj,ak), (bi,bj,bk)) ->+ Monad.lift3 MultiValue.zip3+ (intersectCode ai bi)+ (intersectCode aj bj)+ (intersectCode ak bk)+ sizeCode nml =+ case MultiValue.unzip3 nml of+ (n,m,l) ->+ Monad.liftJoin2 A.mul (sizeCode n) $+ Monad.liftJoin2 A.mul (sizeCode m) (sizeCode l)+ size (n,m,l) = size n * size m * size l+ flattenIndexRec nml ijk =+ case (MultiValue.unzip3 nml, MultiValue.unzip3 ijk) of+ ((n,m,l), (i,j,k)) -> do+ (ns, il) <- flattenIndexRec n i+ (ms, jl) <- flattenIndexRec m j+ x0 <- A.add jl =<< A.mul ms il+ (ls, kl) <- flattenIndexRec l k+ x1 <- A.add kl =<< A.mul ls x0+ sz <- A.mul ns =<< A.mul ms ls+ return (sz, x1)+ iterator nml =+ case MultiValue.unzip3 nml of+ (n,m,l) ->+ fmap (\(a,(b,c)) -> MultiValue.zip3 a b c) $+ Iter.cartesian (iterator n) $+ Iter.cartesian (iterator m) (iterator l)+ loop code nml =+ case MultiValue.unzip3 nml of+ (n,m,l) ->+ loop (\i -> loop (\j -> loop (\k ->+ code (MultiValue.zip3 i j k))+ l) m) n
src/Data/Array/Knead/Simple/Fold.hs view
@@ -20,12 +20,12 @@ import qualified Data.Array.Knead.Simple.Private as Core import Data.Array.Knead.Simple.Private (Array(Array), Code, Val, ) -import qualified Data.Array.Knead.Index.Linear as Linear-import qualified Data.Array.Knead.Index.Linear.Int as IndexInt-import qualified Data.Array.Knead.Index.Nested.Shape as Shape+import qualified Data.Array.Knead.Shape.Cubic as Linear+import qualified Data.Array.Knead.Shape.Cubic.Int as IndexInt+import qualified Data.Array.Knead.Shape.Nested as Shape import qualified Data.Array.Knead.Expression as Expr import Data.Array.Knead.Expression (Exp, unExp, )-import Data.Array.Knead.Index.Linear ((#:.), (:.)((:.)), )+import Data.Array.Knead.Shape.Cubic ((#:.), (:.)((:.)), ) import qualified LLVM.Extra.Multi.Value as MultiValue import LLVM.Extra.Multi.Value (atom, )@@ -75,8 +75,7 @@ (Val (Linear.Index sh) -> Code r a) fold1CodeLinear f nc code ix = Core.fold1Code f (IndexInt.decons nc)- (\jx j -> code (jx #:. IndexInt.cons j))- ix+ (\j -> code (ix #:. IndexInt.cons j)) fold :: (MultiValue.C a) =>
src/Data/Array/Knead/Simple/Physical.hs view
@@ -9,7 +9,7 @@ with, render, scanl1,- mapAccumL,+ mapAccumLSimple, scatter, scatterMaybe, permute,@@ -17,7 +17,7 @@ import qualified Data.Array.Knead.Simple.PhysicalPrivate as Priv import qualified Data.Array.Knead.Simple.Private as Sym-import qualified Data.Array.Knead.Index.Nested.Shape as Shape+import qualified Data.Array.Knead.Shape.Nested as Shape import qualified Data.Array.Knead.Expression as Expr import qualified Data.Array.Knead.Code as Code import Data.Array.Knead.Expression (Exp, unExp, )@@ -39,7 +39,6 @@ import Control.Monad.HT (void, ) import Control.Applicative (liftA2, (<$>), )-import Data.Word (Word32, ) import Prelude hiding (scanl1, ) @@ -101,7 +100,7 @@ type Importer f = FunPtr f -> f foreign import ccall safe "dynamic" callShaper ::- Importer (Ptr sh -> IO Word32)+ Importer (Ptr sh -> IO Shape.Size) foreign import ccall safe "dynamic" callRenderer :: Importer (Ptr sh -> Ptr am -> IO ())@@ -147,18 +146,11 @@ scanl1 :: (Shape.C sh, Storable sh, MultiValueMemory.C sh,- Storable a, MultiValueMemory.C a) =>- (Exp a -> Exp a -> Exp a) ->- Sym.Array (sh, Word32) a -> IO (Array (sh, Word32) a)-scanl1 = scanl1Gen--scanl1Gen ::- (Shape.C sh, Storable sh, MultiValueMemory.C sh, Shape.C n, Storable n, MultiValueMemory.C n, Storable a, MultiValueMemory.C a) => (Exp a -> Exp a -> Exp a) -> Sym.Array (sh, n) a -> IO (Array (sh, n) a)-scanl1Gen f (Sym.Array esh code) =+scanl1 f (Sym.Array esh code) = materialize "scanl1" esh $ \sptr ptr -> do (sh, n) <- MultiValue.unzip <$> Shape.load esh sptr let step ix ptrStart =@@ -172,7 +164,7 @@ return (ptr1, Maybe.just acc1) void $ Shape.loop step sh ptr -mapAccumL ::+mapAccumLSimple :: (Shape.C sh, Storable sh, MultiValueMemory.C sh, Shape.C n, Storable n, MultiValueMemory.C n, MultiValue.C acc,@@ -180,9 +172,9 @@ Storable y, MultiValueMemory.C y) => (Exp acc -> Exp x -> Exp (acc,y)) -> Sym.Array sh acc -> Sym.Array (sh, n) x -> IO (Array (sh, n) y)-mapAccumL f arrInit arrData =- materialize "mapAccumL" (Sym.shape arrData) $- Priv.mapAccumL f arrInit arrData+mapAccumLSimple f arrInit arrData =+ materialize "mapAccumLSimple" (Sym.shape arrData) $+ Priv.mapAccumLSimple f arrInit arrData scatterMaybe :: (Shape.C sh0, Shape.Index sh0 ~ ix0,
src/Data/Array/Knead/Simple/PhysicalPrivate.hs view
@@ -2,7 +2,7 @@ module Data.Array.Knead.Simple.PhysicalPrivate where import qualified Data.Array.Knead.Simple.Private as Sym-import qualified Data.Array.Knead.Index.Nested.Shape as Shape+import qualified Data.Array.Knead.Shape.Nested as Shape import qualified Data.Array.Knead.Expression as Expr import Data.Array.Knead.Expression (Exp, unExp) import Data.Array.Knead.Code (getElementPtr)@@ -15,9 +15,9 @@ import qualified LLVM.Core as LLVM -import Foreign.Storable (Storable, ) import Foreign.Ptr (Ptr, ) +import qualified Control.Applicative.HT as App import Control.Monad.HT (void, ) import Control.Applicative ((<$>), ) @@ -25,62 +25,177 @@ -mapAccumL ::- (Shape.C sh, Storable sh, MultiValueMemory.C sh,- Shape.C n, Storable n, MultiValueMemory.C n,+writeArray ::+ (Shape.C sh, Memory.C a) =>+ MultiValue.T sh ->+ (MultiValue.T (Shape.Index sh) -> LLVM.CodeGenFunction r a) ->+ LLVM.Value (Ptr (Memory.Struct a)) ->+ LLVM.CodeGenFunction r (LLVM.Value (Ptr (Memory.Struct a)))+writeArray sh code ptr = do+ let clear ix p = do+ flip Memory.store p =<< code ix+ A.advanceArrayElementPtr p+ Shape.loop clear sh ptr+++mapAccumLLoop ::+ (MultiValue.C acc,+ MultiValueMemory.C b, MultiValueMemory.Struct b ~ bm,+ Shape.C sh, Shape.Index sh ~ ix) =>+ (MultiValue.T ix -> LLVM.CodeGenFunction r (MultiValue.T a)) ->+ (Exp acc -> Exp a -> Exp (acc, b)) ->+ MultiValue.T sh ->+ LLVM.Value (Ptr bm) -> MultiValue.T acc ->+ LLVM.CodeGenFunction r (LLVM.Value (Ptr bm), MultiValue.T acc)+mapAccumLLoop code f n yPtr accInit = do+ let step k0 (ptr0, acc0) = do+ x <- code k0+ (acc1,y) <- MultiValue.unzip <$> Expr.unliftM2 f acc0 x+ Memory.store y ptr0+ ptr1 <- A.advanceArrayElementPtr ptr0+ return (ptr1, acc1)+ Shape.loop step n (yPtr, accInit)++mapAccumLSimple ::+ (Shape.C sh, MultiValueMemory.C sh,+ Shape.C n, MultiValueMemory.C n, MultiValue.C acc,- Storable x, MultiValueMemory.C x,- Storable y, MultiValueMemory.C y) =>+ MultiValueMemory.C x,+ MultiValueMemory.C y) => (Exp acc -> Exp x -> Exp (acc,y)) -> Sym.Array sh acc -> Sym.Array (sh, n) x -> LLVM.Value (Ptr (MultiValueMemory.Struct (sh,n))) -> LLVM.Value (Ptr (MultiValueMemory.Struct y)) -> LLVM.CodeGenFunction r ()-mapAccumL f (Sym.Array _ initCode) (Sym.Array esh code) sptr ptr = do+mapAccumLSimple f (Sym.Array _ initCode) (Sym.Array esh code) sptr ptr = do (sh, n) <- MultiValue.unzip <$> Shape.load esh sptr let step ix ptrStart = do accInit <- initCode ix- fmap fst $- (\body -> Shape.loop body n (ptrStart, accInit)) $- \k0 (ptr0, acc0) -> do- x <- code $ MultiValue.zip ix k0- (acc1,y) <- MultiValue.unzip <$> Expr.unliftM2 f acc0 x- Memory.store y ptr0- ptr1 <- A.advanceArrayElementPtr ptr0- return (ptr1, acc1)+ fst <$> mapAccumLLoop (code . MultiValue.zip ix) f n ptrStart accInit void $ Shape.loop step sh ptr +mapAccumLSequence ::+ (Shape.C n, MultiValueMemory.C n,+ MultiValue.C acc, MultiValueMemory.C final,+ MultiValueMemory.C x,+ MultiValueMemory.C y) =>+ (Exp acc -> Exp x -> Exp (acc,y)) ->+ (Exp acc -> Exp final) ->+ Exp acc -> Sym.Array n x ->+ LLVM.Value (Ptr (MultiValueMemory.Struct final)) ->+ LLVM.Value (Ptr (MultiValueMemory.Struct n)) ->+ LLVM.Value (Ptr (MultiValueMemory.Struct y)) ->+ LLVM.CodeGenFunction r ()+mapAccumLSequence f final initExp (Sym.Array esh code) accPtr sptr yPtr = do+ n <- Shape.load esh sptr+ accInit <- unExp initExp+ accExit <- snd <$> mapAccumLLoop code f n yPtr accInit+ flip Memory.store accPtr =<< Expr.unliftM1 final accExit++mapAccumL ::+ (Shape.C sh, MultiValueMemory.C sh,+ Shape.C n, MultiValueMemory.C n,+ MultiValue.C acc, MultiValueMemory.C final,+ MultiValueMemory.C x,+ MultiValueMemory.C y) =>+ (Exp acc -> Exp x -> Exp (acc,y)) ->+ (Exp acc -> Exp final) ->+ Sym.Array sh acc -> Sym.Array (sh, n) x ->+ (LLVM.Value (Ptr (MultiValueMemory.Struct sh)),+ LLVM.Value (Ptr (MultiValueMemory.Struct final))) ->+ (LLVM.Value (Ptr (MultiValueMemory.Struct (sh,n))),+ LLVM.Value (Ptr (MultiValueMemory.Struct y))) ->+ LLVM.CodeGenFunction r ()+mapAccumL f final (Sym.Array _ initCode) (Sym.Array esh code)+ (_, accPtr) (sptr, yPtr) = do+ (sh, n) <- MultiValue.unzip <$> Shape.load esh sptr+ let step ix (accPtr0, yPtrStart) = do+ accInit <- initCode ix+ (ptrStop, accExit) <-+ mapAccumLLoop (code . MultiValue.zip ix) f n yPtrStart accInit+ flip Memory.store accPtr0 =<< Expr.unliftM1 final accExit+ accPtr1 <- A.advanceArrayElementPtr accPtr0+ return (accPtr1, ptrStop)+ void $ Shape.loop step sh (accPtr,yPtr)+ foldOuterL ::- (Shape.C sh, Storable sh, MultiValueMemory.C sh,- Shape.C n, Storable n, MultiValueMemory.C n,+ (Shape.C sh, MultiValueMemory.C sh,+ Shape.C n, MultiValueMemory.C n, MultiValueMemory.C a) => (Exp a -> Exp b -> Exp a) -> Sym.Array sh a -> Sym.Array (n,sh) b -> LLVM.Value (Ptr (MultiValueMemory.Struct sh)) -> LLVM.Value (Ptr (MultiValueMemory.Struct a)) -> LLVM.CodeGenFunction r ()-foldOuterL f (Sym.Array _ initCode) (Sym.Array esh code) _sptr ptr = do- -- (n,sh) <- MultiValue.unzip <$> Shape.load esh sptr- (n,sh) <- MultiValue.unzip <$> unExp esh- let fillInit ix ptr0 = do- a <- initCode ix- Memory.store a ptr0- A.advanceArrayElementPtr ptr0- void $ Shape.loop fillInit sh ptr+foldOuterL f (Sym.Array _ initCode) (Sym.Array esh code) sptr ptr = do+ sh <- Shape.load (Expr.snd esh) sptr+ n <- MultiValue.fst <$> unExp esh+ void $ writeArray sh initCode ptr let step k ix ptr0 = do- b <- code $ MultiValue.zip k ix- a0 <- Memory.load ptr0- a1 <- Expr.unliftM2 f a0 b- Memory.store a1 ptr0- A.advanceArrayElementPtr ptr0+ b <- code $ MultiValue.zip k ix+ a0 <- Memory.load ptr0+ a1 <- Expr.unliftM2 f a0 b+ Memory.store a1 ptr0+ A.advanceArrayElementPtr ptr0 void $ Shape.loop (\k () -> void $ Shape.loop (step k) sh ptr) n () +{- |+We need a scalar Shape type @n@.+Scalar Shape types could be distinguished from other Shape types+by the fact that you can convert any Index into a Shape.+-}+mapFilter ::+ (Shape.Sequence n, MultiValueMemory.C n,+ MultiValueMemory.C b) =>+ (Exp a -> Exp b) ->+ (Exp a -> Exp Bool) ->+ Sym.Array n a ->+ LLVM.Value (Ptr (MultiValueMemory.Struct n)) ->+ LLVM.Value (Ptr (MultiValueMemory.Struct b)) ->+ LLVM.CodeGenFunction r (MultiValue.T n)+mapFilter f p (Sym.Array esh code) sptr ptr = do+ n <- Shape.load esh sptr+ let step ix (dstPtr,dstIx) = do+ a <- code ix+ MultiValue.Cons c <- Expr.unliftM1 p a+ C.ifThen c (dstPtr,dstIx)+ (do+ flip Memory.store dstPtr =<< Expr.unliftM1 f a+ App.lift2 (,)+ (A.advanceArrayElementPtr dstPtr)+ (MultiValue.inc dstIx))+ Shape.sequenceShapeFromIndex . snd+ =<< Shape.loop step n (ptr, MultiValue.zero)++filterOuter ::+ (Shape.Sequence n, MultiValueMemory.C n,+ Shape.C sh, MultiValueMemory.C sh,+ MultiValueMemory.C a) =>+ Sym.Array n Bool ->+ Sym.Array (n,sh) a ->+ LLVM.Value (Ptr (MultiValueMemory.Struct (n,sh))) ->+ LLVM.Value (Ptr (MultiValueMemory.Struct a)) ->+ LLVM.CodeGenFunction r (MultiValue.T (n,sh))+filterOuter (Sym.Array _eish selectCode) (Sym.Array esh code) sptr ptr = do+ (n,sh) <- MultiValue.unzip <$> Shape.load esh sptr+ let step k (dstPtr0,dstK) = do+ MultiValue.Cons c <- selectCode k+ C.ifThen c (dstPtr0,dstK)+ (do+ dstPtr1 <- writeArray sh (code . MultiValue.zip k) dstPtr0+ (,) dstPtr1 <$> MultiValue.inc dstK)+ finalN <-+ Shape.sequenceShapeFromIndex . snd+ =<< Shape.loop step n (ptr, MultiValue.zero)+ return $ MultiValue.zip finalN sh++ scatterMaybe :: (Shape.C sh0, Shape.Index sh0 ~ ix0, Shape.C sh1, Shape.Index sh1 ~ ix1,- Storable sh1, MultiValueMemory.C sh1,- Storable a, MultiValueMemory.C a) =>+ MultiValueMemory.C sh1,+ MultiValueMemory.C a) => (Exp a -> Exp a -> Exp a) -> Sym.Array sh1 a -> Sym.Array sh0 (Maybe (ix1, a)) -> LLVM.Value (Ptr (MultiValueMemory.Struct sh1)) ->@@ -89,11 +204,8 @@ scatterMaybe accum (Sym.Array esh codeInit) (Sym.Array eish codeMap) sptr ptr = do - let clear ix p = do- flip Memory.store p =<< codeInit ix- A.advanceArrayElementPtr p sh <- Shape.load esh sptr- void $ Shape.loop clear sh ptr+ void $ writeArray sh codeInit ptr ish <- unExp eish let fill ix () = do@@ -109,8 +221,8 @@ scatter :: (Shape.C sh0, Shape.Index sh0 ~ ix0, Shape.C sh1, Shape.Index sh1 ~ ix1,- Storable sh1, MultiValueMemory.C sh1,- Storable a, MultiValueMemory.C a) =>+ MultiValueMemory.C sh1,+ MultiValueMemory.C a) => (Exp a -> Exp a -> Exp a) -> Sym.Array sh1 a -> Sym.Array sh0 (Shape.Index sh1, a) ->@@ -118,17 +230,32 @@ LLVM.Value (Ptr (MultiValueMemory.Struct a)) -> LLVM.CodeGenFunction r () scatter accum (Sym.Array esh codeInit) (Sym.Array eish codeMap) sptr ptr = do- let clear ix p = do- flip Memory.store p =<< codeInit ix- A.advanceArrayElementPtr p sh <- Shape.load esh sptr- void $ Shape.loop clear sh ptr+ void $ writeArray sh codeInit ptr ish <- unExp eish let fill ix () = do- (jx, a) <- fmap MultiValue.unzip $ codeMap ix+ (jx, a) <- MultiValue.unzip <$> codeMap ix p <- getElementPtr sh ptr jx flip Memory.store p =<< Expr.unliftM2 (flip accum) a =<< Memory.load p Shape.loop fill ish ()++addDimension ::+ (Shape.C n, MultiValueMemory.C n, Shape.Index n ~ k,+ Shape.C sh, MultiValueMemory.C sh,+ MultiValueMemory.C b) =>+ Exp n ->+ (Exp k -> Exp a -> Exp b) ->+ Sym.Array sh a ->+ LLVM.Value (Ptr (MultiValueMemory.Struct (sh,n))) ->+ LLVM.Value (Ptr (MultiValueMemory.Struct b)) ->+ LLVM.CodeGenFunction r ()+addDimension en select (Sym.Array esh code) sptr ptr = do+ (sh,n) <- MultiValue.unzip <$> Shape.load (Expr.zip esh en) sptr++ let fill ix ptr0 = do+ a <- code ix+ writeArray n (\k -> Expr.unliftM2 select k a) ptr0+ void $ Shape.loop fill sh ptr
src/Data/Array/Knead/Simple/Private.hs view
@@ -2,17 +2,17 @@ {-# LANGUAGE TypeFamilies #-} module Data.Array.Knead.Simple.Private where -import qualified Data.Array.Knead.Index.Nested.Shape as Shape+import qualified Data.Array.Knead.Shape.Nested as Shape import qualified Data.Array.Knead.Expression as Expr import Data.Array.Knead.Expression (Exp(Exp), ) import qualified LLVM.Extra.Multi.Value as MultiValue-import qualified LLVM.Extra.Monad as Monad+import qualified LLVM.Extra.Iterator as Iter import qualified LLVM.Extra.Maybe as Maybe-import qualified LLVM.Extra.Control as C import qualified LLVM.Core as LLVM import qualified Control.Category as Cat+import qualified Control.Monad.HT as Monad import Control.Monad ((<=<), ) import Prelude hiding (id, map, zipWith, replicate, )@@ -86,15 +86,15 @@ lift2 $ \(Array _sha codeA) (Array _shb codeB) -> Array sh (\ix ->- Monad.liftR2 (Expr.unliftM2 f)+ Monad.liftJoin2 (Expr.unliftM2 f) (codeA =<< Expr.unliftM1 projectIndex0 ix) (codeB =<< Expr.unliftM1 projectIndex1 ix)) id ::- (Shape.C sh, Shape.Index sh ~ ix) =>- Exp sh -> Array sh ix-id sh = Array sh return+ (C array, Shape.C sh, Shape.Index sh ~ ix) =>+ Exp sh -> array sh ix+id sh = lift0 $ Array sh return map :: (C array, Shape.C sh) =>@@ -114,17 +114,17 @@ fold1Code ::- (Shape.C sh1, Shape.Index sh1 ~ ix1, MultiValue.C a) =>+ (Shape.C sh, Shape.Index sh ~ ix, MultiValue.C a) => (Exp a -> Exp a -> Exp a) ->- Exp sh1 ->- (Val ix0 -> Val ix1 -> Code r a) ->- (Val ix0 -> Code r a)-fold1Code f (Exp nc) code ix = do+ Exp sh ->+ (Val ix -> Code r a) ->+ Code r a+fold1Code f (Exp nc) code = do n <- nc fmap Maybe.fromJust $ Shape.loop (\i0 macc0 -> do- a <- code ix i0+ a <- code i0 acc1 <- Maybe.run macc0 (return a) (flip (Expr.unliftM2 f) a) return $ Maybe.just acc1) n Maybe.nothing@@ -136,25 +136,16 @@ fold1 f = lift1 $ \(Array shs code) -> case Expr.unzip shs of- (sh, s) -> Array sh $ fold1Code f s $ MultiValue.curry code+ (sh, s) -> Array sh $ fold1Code f s . MultiValue.curry code fold1All :: (Shape.C sh, MultiValue.C a) => (Exp a -> Exp a -> Exp a) ->- Array sh a -> Array () a-fold1All f (Array esh code) =- fold1 f $- Array- (Expr.lift1 (MultiValue.zip (MultiValue.Cons ())) esh)- (code . MultiValue.snd)+ Array sh a -> Exp a+fold1All f (Array sh code) = Exp (fold1Code f sh code) -{--'Shape.loop' does not support an early exit.-I wished the LLVM optimizer would rewrite the loop accordingly.-Unfortunately, it does not.--} findAllCode :: (Shape.C sh, Shape.Index sh ~ ix, MultiValue.C a) => (Exp a -> Exp Bool) ->@@ -164,23 +155,20 @@ findAllCode p (Exp sh) code = do n <- sh finalFound <-- Shape.loop- (\i found ->- C.ifThenElse (Maybe.isJust found)- (return found)- (do- a <- code i- MultiValue.Cons b <- Expr.unliftM1 p a- return $ Maybe.fromBool b a))- n Maybe.nothing+ Iter.mapWhileState_+ (\a _found -> do+ MultiValue.Cons b <- Expr.unliftM1 p a+ notb <- LLVM.inv b+ return (notb, Maybe.fromBool b a))+ (Iter.mapM code $ Shape.iterator n)+ Maybe.nothing Maybe.run finalFound (return MultiValue.nothing) (return . MultiValue.just) {- | In principle this can be implemented using fold1All-but this one should have short-cut semantics.-Currently it has not! :-(+but it has a short-cut semantics. @All@ means that it scans all dimensions but it does not mean that it finds all occurrences. If you want to get the index of the found element,
src/Data/Array/Knead/Simple/ShapeDependent.hs view
@@ -4,12 +4,11 @@ import qualified Data.Array.Knead.Simple.Private as Core import Data.Array.Knead.Simple.Private (Array(Array), ) -import qualified Data.Array.Knead.Index.Nested.Shape as Shape+import qualified Data.Array.Knead.Shape.Nested as Shape import qualified Data.Array.Knead.Expression as Expr import Data.Array.Knead.Expression (Exp, ) -import qualified LLVM.Extra.Monad as Monad-+import qualified Control.Monad.HT as Monad import Control.Monad ((<=<), ) @@ -62,7 +61,7 @@ Core.lift2 $ \(Array sha codeA) (Array shb codeB) -> Array (combineShape sha shb) (\ix ->- Monad.liftR2 (Expr.unliftM2 f)+ Monad.liftJoin2 (Expr.unliftM2 f) (codeA =<< Expr.unliftM1 projectIndex0 ix) (codeB =<< Expr.unliftM1 projectIndex1 ix))
src/Data/Array/Knead/Simple/Slice.hs view
@@ -69,10 +69,10 @@ import qualified Data.Array.Knead.Simple.ShapeDependent as ShapeDep import qualified Data.Array.Knead.Simple.Private as Core -import qualified Data.Array.Knead.Index.Linear as Linear-import qualified Data.Array.Knead.Index.Nested.Shape as Shape+import qualified Data.Array.Knead.Shape.Cubic as Linear+import qualified Data.Array.Knead.Shape.Nested as Shape import qualified Data.Array.Knead.Expression as Expr-import Data.Array.Knead.Index.Linear ((#:.), (:.)((:.)), )+import Data.Array.Knead.Shape.Cubic ((#:.), (:.)((:.)), ) import Data.Array.Knead.Expression (Exp, ) import qualified LLVM.Extra.Multi.Value as MultiValue
src/Data/Array/Knead/Simple/Symbolic.hs view
@@ -4,6 +4,7 @@ Core.Array, Core.C(..), Exp,+ fix, shape, (Core.!), Core.the,@@ -21,24 +22,29 @@ zip, zip3, zip4,- fold1,- fold1All,+ Core.fold1,+ Core.fold1All, Core.findAll, ) where import qualified Data.Array.Knead.Simple.ShapeDependent as ShapeDep import qualified Data.Array.Knead.Simple.Private as Core-import Data.Array.Knead.Simple.Private (Array, shape, fold1, gather, )+import Data.Array.Knead.Simple.Private (Array, shape, gather, ) -import qualified Data.Array.Knead.Index.Nested.Shape as Shape+import qualified Data.Array.Knead.Shape.Nested as Shape import qualified Data.Array.Knead.Expression as Expr import Data.Array.Knead.Expression (Exp, ) import qualified LLVM.Extra.Multi.Value as MultiValue +import Data.Function.HT (Id)+ import Prelude hiding (zipWith, zipWith3, zip, zip3, replicate, ) +fix :: Id (Array sh a)+fix = id+ backpermute :: (Shape.C sh0, Shape.Index sh0 ~ ix0, Shape.C sh1, Shape.Index sh1 ~ ix1,@@ -85,16 +91,3 @@ array sh a -> array sh b -> array sh c -> array sh d -> array sh (a,b,c,d) zip4 = zipWith4 (Expr.lift4 MultiValue.zip4)---fold1All ::- (Core.C array, Shape.C sh, Shape.Scalar z, MultiValue.C a) =>- (Exp a -> Exp a -> Exp a) ->- array sh a -> array z a-fold1All f =- Core.lift1 $ \arr ->- fold1 f $- backpermute- (Expr.lift2 MultiValue.zip Shape.scalar (shape arr))- (Expr.lift1 MultiValue.snd)- arr