knead 0.3 → 0.4
raw patch · 19 files changed
+636/−637 lines, 19 filesdep +comfort-array
Dependencies added: comfort-array
Files
- knead.cabal +4/−3
- src/Data/Array/Knead/Code.hs +2/−2
- src/Data/Array/Knead/Expression.hs +4/−2
- src/Data/Array/Knead/Parameterized/Physical.hs +7/−5
- src/Data/Array/Knead/Parameterized/PhysicalHull.hs +23/−22
- src/Data/Array/Knead/Parameterized/Private.hs +1/−1
- src/Data/Array/Knead/Parameterized/Render.hs +1/−1
- src/Data/Array/Knead/Parameterized/Slice.hs +1/−1
- src/Data/Array/Knead/Parameterized/Symbolic.hs +1/−1
- src/Data/Array/Knead/Shape.hs +498/−0
- src/Data/Array/Knead/Shape/Cubic.hs +66/−23
- src/Data/Array/Knead/Shape/Nested.hs +0/−539
- src/Data/Array/Knead/Simple/Fold.hs +3/−2
- src/Data/Array/Knead/Simple/Physical.hs +20/−30
- src/Data/Array/Knead/Simple/PhysicalPrivate.hs +1/−1
- src/Data/Array/Knead/Simple/Private.hs +1/−1
- src/Data/Array/Knead/Simple/ShapeDependent.hs +1/−1
- src/Data/Array/Knead/Simple/Slice.hs +1/−1
- src/Data/Array/Knead/Simple/Symbolic.hs +1/−1
knead.cabal view
@@ -1,5 +1,5 @@ Name: knead-Version: 0.3+Version: 0.4 License: BSD3 License-File: LICENSE Author: Henning Thielemann <haskell@henning-thielemann.de>@@ -49,7 +49,7 @@ Build-Type: Simple Source-Repository this- Tag: 0.3+ Tag: 0.4 Type: darcs Location: http://hub.darcs.net/thielema/knead/ @@ -62,6 +62,7 @@ llvm-extra >=0.8 && <0.9, llvm-tf >=3.1.1 && <3.2, tfp >=1.0 && <1.1,+ comfort-array >=0.3 && <0.5, storable-tuple >=0.0 && <0.1, storable-record >=0.0.3 && <0.1, bool8 >=0.0 && <0.1,@@ -72,7 +73,7 @@ GHC-Options: -Wall Hs-Source-Dirs: src Exposed-Modules:- Data.Array.Knead.Shape.Nested+ Data.Array.Knead.Shape Data.Array.Knead.Shape.Cubic Data.Array.Knead.Shape.Cubic.Int Data.Array.Knead.Expression
src/Data/Array/Knead/Code.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE TypeFamilies #-} module Data.Array.Knead.Code where -import qualified Data.Array.Knead.Shape.Nested as Shape+import qualified Data.Array.Knead.Shape as Shape import qualified LLVM.Extra.Multi.Value as MultiValue @@ -23,7 +23,7 @@ MultiValue.T ix -> LLVM.CodeGenFunction r (LLVM.Value (Ptr a)) getElementPtr sh ptr ix = do- n <- Shape.flattenIndex sh ix+ n <- Shape.offset sh ix LLVM.getElementPtr ptr (n, ())
src/Data/Array/Knead/Expression.hs view
@@ -244,7 +244,8 @@ patternA -> patternB -> (Decomposed Exp patternA -> Decomposed Exp patternB -> a) ->- Exp (PatternTuple patternA) -> Exp (PatternTuple patternB) -> Exp (Composed a)+ Exp (PatternTuple patternA) ->+ Exp (PatternTuple patternB) -> Exp (Composed a) modify2 pa pb f a b = compose $ f (decompose pa a) (decompose pb b) @@ -277,7 +278,8 @@ instance (Compose a, Compose b, Compose c) => Compose (a,b,c) where type Composed (a,b,c) = (Composed a, Composed b, Composed c)- compose = TupleHT.uncurry3 zip3 . TupleHT.mapTriple (compose, compose, compose)+ compose =+ TupleHT.uncurry3 zip3 . TupleHT.mapTriple (compose, compose, compose) instance (Decompose pa, Decompose pb, Decompose pc) =>
src/Data/Array/Knead/Parameterized/Physical.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE ForeignFunctionInterface #-} module Data.Array.Knead.Parameterized.Physical ( Phys.Array,- Phys.shape,+ Array.shape, Phys.fromList, feed, the,@@ -20,12 +20,14 @@ 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.Shape.Nested as Shape+import qualified Data.Array.Knead.Shape 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 (getElementPtr, compile, ) +import qualified Data.Array.Comfort.Storable.Unchecked as Array+ import qualified LLVM.Extra.Multi.Value.Memory as MultiValueMemory import qualified LLVM.Extra.Multi.Value as MultiValue import qualified LLVM.Extra.Memory as Memory@@ -50,7 +52,7 @@ MultiValueMemory.C a) => Param.T p (Phys.Array sh a) -> Sym.Array p sh a feed arr =- Param.withMulti (fmap Phys.shape arr) $ \getShape valueShape ->+ Param.withMulti (fmap Array.shape arr) $ \getShape valueShape -> Sym.Array (\p -> case mapFst valueShape $ MultiValue.unzip p of@@ -58,7 +60,7 @@ Core.Array (Expr.lift0 sh) $ Memory.load <=< getElementPtr sh ptr) (\p ->- case Phys.buffer $ Param.get arr p of+ case Array.buffer $ Param.get arr p of fptr -> withForeignPtr fptr $ \ptr -> return (fptr, (getShape p, MultiValueMemory.castStructPtr ptr)))@@ -110,7 +112,7 @@ Core.Array esh _code -> do sh <- unExp esh MultiValueMemory.store sh resultPtr- Shape.sizeCode sh >>= LLVM.ret+ Shape.size sh >>= LLVM.ret return $ \p -> bracket (create p) (delete . fst) $ \(_ctx, param) -> alloca $ \shptr ->
src/Data/Array/Knead/Parameterized/PhysicalHull.hs view
@@ -24,14 +24,15 @@ 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.Shape.Nested as Shape+import qualified Data.Array.Knead.Shape 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, ) +import Data.Array.Comfort.Storable.Unchecked (Array(Array))+ import qualified LLVM.Extra.Multi.Value.Memory as MultiValueMemory import qualified LLVM.Extra.Multi.Value as MultiValue import qualified LLVM.Extra.Memory as Memory@@ -84,7 +85,7 @@ LLVM.Value (Ptr (MultiValueMemory.Struct sh)) -> LLVM.Value (Ptr (MultiValueMemory.Struct a)) -> LLVM.CodeGenFunction () ()) ->- Sym.Hull p core -> IO (p -> IO (Phys.Array sh a))+ Sym.Hull p core -> IO (p -> IO (Array sh a)) materialize name shape fill (Sym.Hull core create delete) = do (fsh, farr) <- compile name $@@ -94,7 +95,7 @@ param <- Memory.load paramPtr sh <- unExp $ shape $ core param MultiValueMemory.store sh resultPtr- Shape.sizeCode sh >>= LLVM.ret)+ Shape.size sh >>= LLVM.ret) (Code.createFunction callFill "fill" $ \paramPtr shapePtr bufferPtr -> do param <- Memory.load paramPtr@@ -110,7 +111,7 @@ fptr <- mallocArray =<< fsh paramMVPtr shapeMVPtr withForeignMemPtr fptr $ farr paramMVPtr shapeMVPtr sh <- peek shptr- return (Phys.Array sh fptr)+ return (Array sh fptr) foreign import ccall safe "dynamic" callFillExpArray ::@@ -128,7 +129,7 @@ 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))+ Sym.Hull p core -> IO (p -> IO (b, Array sh a)) materializeExpArray name shape fill (Sym.Hull core create delete) = do (fsh, farr) <- compile name $@@ -138,7 +139,7 @@ param <- Memory.load paramPtr sh <- unExp $ shape $ core param MultiValueMemory.store sh resultPtr- Shape.sizeCode sh >>= LLVM.ret)+ Shape.size sh >>= LLVM.ret) (Code.createFunction callFillExpArray "fill" $ \paramPtr finalPtr shapePtr bufferPtr -> do param <- Memory.load paramPtr@@ -157,7 +158,7 @@ withForeignMemPtr fptr $ farr paramMVPtr finalMVPtr shapeMVPtr sh <- peek shptr final <- peek finalPtr- return (final, Phys.Array sh fptr)+ return (final, Array sh fptr) foreign import ccall safe "dynamic" callShaper2 ::@@ -180,7 +181,7 @@ (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))+ Sym.Hull p core -> IO (p -> IO (Array sha a, Array shb b)) materialize2 name shape fill (Sym.Hull core create delete) = do (fsh, farr) <- compile name $@@ -192,9 +193,9 @@ MultiValueMemory.store sha shapeAPtr MultiValueMemory.store shb shapeBPtr sizeAPtr <- LLVM.bitcast sizesPtr- flip LLVM.store sizeAPtr =<< Shape.sizeCode sha+ flip LLVM.store sizeAPtr =<< Shape.size sha sizeBPtr <- A.advanceArrayElementPtr sizeAPtr- flip LLVM.store sizeBPtr =<< Shape.sizeCode shb+ flip LLVM.store sizeBPtr =<< Shape.size shb LLVM.ret ()) (Code.createFunction callFill2 "fill" $ \paramPtr shapeAPtr bufferAPtr shapeBPtr bufferBPtr -> do@@ -219,14 +220,14 @@ farr paramMVPtr shapeAMVPtr aptr shapeBMVPtr bptr sha <- peek shaPtr shb <- peek shbPtr- return (Phys.Array sha afptr, Phys.Array shb bfptr)+ return (Array sha afptr, Array shb bfptr) render :: (Shape.C sh, Shape.Index sh ~ ix, Storable sh, MultiValueMemory.C sh, Storable a, MultiValueMemory.C a) =>- Sym.Hull p (Core.Array sh a) -> IO (p -> IO (Phys.Array sh a))+ Sym.Hull p (Core.Array sh a) -> IO (p -> IO (Array sh a)) render = materialize "render" Core.shape (\(Core.Array esh code) shapePtr bufferPtr -> do@@ -249,7 +250,7 @@ Shape.C sh1, Shape.Index sh1 ~ ix1, Storable sh1, MultiValueMemory.C sh1, Storable a, MultiValueMemory.C a) =>- Sym.Hull p (Scatter sh0 sh1 a) -> IO (p -> IO (Phys.Array sh1 a))+ Sym.Hull p (Scatter sh0 sh1 a) -> IO (p -> IO (Array sh1 a)) scatter = materialize "scatter" (Core.shape . scatterInit)@@ -270,7 +271,7 @@ Shape.C sh1, Shape.Index sh1 ~ ix1, Storable sh1, MultiValueMemory.C sh1, Storable a, MultiValueMemory.C a) =>- Sym.Hull p (ScatterMaybe sh0 sh1 a) -> IO (p -> IO (Phys.Array sh1 a))+ Sym.Hull p (ScatterMaybe sh0 sh1 a) -> IO (p -> IO (Array sh1 a)) scatterMaybe = materialize "scatterMaybe" (Core.shape . scatterMaybeInit)@@ -291,7 +292,7 @@ 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))+ Sym.Hull p (MapAccumLSimple sh n acc a b) -> IO (p -> IO (Array (sh,n) b)) mapAccumLSimple = materialize "mapAccumLSimple" (Core.shape . mapAccumLSimpleArray)@@ -315,7 +316,7 @@ 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))+ IO (p -> IO (final, Array n b)) mapAccumLSequence = materializeExpArray "mapAccumLSequence" (Core.shape . mapAccumLSequenceArray)@@ -340,7 +341,7 @@ Storable a, MultiValueMemory.C a, Storable b, MultiValueMemory.C b) => Sym.Hull p (MapAccumL sh n acc final a b) ->- IO (p -> IO (Phys.Array sh final, Phys.Array (sh,n) b))+ IO (p -> IO (Array sh final, Array (sh,n) b)) mapAccumL = materialize2 "mapAccumL" (\core ->@@ -363,7 +364,7 @@ (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))+ Sym.Hull p (FoldOuterL n sh a b) -> IO (p -> IO (Array sh a)) foldOuterL = materialize "foldOuterL" (Core.shape . foldOuterLInit)@@ -381,7 +382,7 @@ (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))+ Sym.Hull p (MapFilter n a b) -> IO (p -> IO (Array n b)) mapFilter = materialize "mapFilter" (Core.shape . mapFilterArray)@@ -401,7 +402,7 @@ (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))+ Sym.Hull p (FilterOuter n sh a) -> IO (p -> IO (Array (n,sh) a)) filterOuter = materialize "filterOuter" (Core.shape . filterOuterArray)@@ -421,7 +422,7 @@ (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))+ Sym.Hull p (AddDimension sh n a b) -> IO (p -> IO (Array (sh,n) b)) addDimension = materialize "addDimension" (\r -> Expr.zip (Core.shape (addDimensionArray r)) (addDimensionSize r))
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.Shape.Nested as Shape+import qualified Data.Array.Knead.Shape as Shape import qualified Data.Array.Knead.Expression as Expr import Data.Array.Knead.Expression (Exp, )
src/Data/Array/Knead/Parameterized/Render.hs view
@@ -21,7 +21,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.Shape.Nested as Shape+import qualified Data.Array.Knead.Shape as Shape import Data.Array.Knead.Parameterized.PhysicalHull (MapFilter, FilterOuter, MapAccumLSimple, MapAccumLSequence, MapAccumL, FoldOuterL,
src/Data/Array/Knead/Parameterized/Slice.hs view
@@ -18,7 +18,7 @@ import qualified Data.Array.Knead.Simple.Private as Core import qualified Data.Array.Knead.Shape.Cubic as Linear-import qualified Data.Array.Knead.Shape.Nested as Shape+import qualified Data.Array.Knead.Shape 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/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.Shape.Nested as Shape+import qualified Data.Array.Knead.Shape 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.hs view
@@ -0,0 +1,498 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE FlexibleContexts #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+module Data.Array.Knead.Shape (+ C(..), Index,+ Size,+ value,+ paramWith,+ load,+ intersect,+ offset,++ ZeroBased(ZeroBased), zeroBased, zeroBasedSize,++ Range(Range), range, rangeFrom, rangeTo,+ Shifted(Shifted), shifted, shiftedOffset, shiftedSize,++ 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 Data.Array.Comfort.Shape as Shape+import Data.Array.Comfort.Shape+ (Index, ZeroBased(ZeroBased), Range(Range), Shifted(Shifted))+import Data.Ix (Ix)++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)+import Foreign.Ptr (Ptr)++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++offset ::+ (C sh) =>+ MultiValue.T sh -> MultiValue.T (Index sh) ->+ LLVM.CodeGenFunction r (LLVM.Value Size)+offset sh ix = ($ix) . snd =<< sizeOffset sh++class (MultiValue.C sh, MultiValue.C (Index sh), Shape.Indexed sh) => C sh where+ {-+ 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)+ size :: MultiValue.T sh -> LLVM.CodeGenFunction r (LLVM.Value Size)+ {- |+ Result is @(size, offset)@.+ @size@ must equal the result of 'size'.+ We use this for sharing intermediate results.+ -}+ sizeOffset ::+ MultiValue.T sh ->+ LLVM.CodeGenFunction r+ (LLVM.Value Size,+ MultiValue.T (Index sh) -> LLVM.CodeGenFunction r (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+ intersectCode _ _ = return $ MultiValue.cons ()+ size _ = return A.one+ sizeOffset _ = return (A.one, \_ -> return 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)+++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 Word8 where toSize (MultiValue.Cons n) = LLVM.ext n+instance ToSize Word16 where toSize (MultiValue.Cons n) = LLVM.ext n+instance ToSize Word32 where toSize (MultiValue.Cons n) = LLVM.ext n+instance ToSize Word64 where toSize (MultiValue.Cons n) = return n+instance ToSize Int8 where toSize (MultiValue.Cons n) = LLVM.zext n+instance ToSize Int16 where toSize (MultiValue.Cons n) = LLVM.zext n+instance ToSize Int32 where toSize (MultiValue.Cons n) = LLVM.zext n+instance ToSize Int64 where toSize (MultiValue.Cons n) = LLVM.bitcast n+++unzipZeroBased :: MultiValue.T (ZeroBased n) -> ZeroBased (MultiValue.T n)+unzipZeroBased (MultiValue.Cons (ZeroBased n)) = ZeroBased (MultiValue.Cons n)++zeroBasedSize :: (Expr.Value val) => val (ZeroBased n) -> val n+zeroBasedSize = Expr.lift1 $ Shape.zeroBasedSize . unzipZeroBased++zeroBased :: (Expr.Value val) => val n -> val (ZeroBased n)+zeroBased =+ Expr.lift1 $ \(MultiValue.Cons n) -> MultiValue.Cons (ZeroBased n)++instance (MultiValue.C n) => MultiValue.C (ZeroBased n) where+ type Repr f (ZeroBased n) = ZeroBased (MultiValue.Repr f n)+ cons (ZeroBased n) = zeroBased (MultiValue.cons n)+ undef = zeroBased MultiValue.undef+ zero = zeroBased MultiValue.zero+ phis bb = Monad.lift zeroBased . MultiValue.phis bb . zeroBasedSize+ addPhis bb a b = MultiValue.addPhis bb (zeroBasedSize a) (zeroBasedSize b)++type instance+ MultiValue.Decomposed f (ZeroBased pn) =+ ZeroBased (MultiValue.Decomposed f pn)+type instance+ MultiValue.PatternTuple (ZeroBased pn) =+ ZeroBased (MultiValue.PatternTuple pn)++instance (MultiValue.Compose n) => MultiValue.Compose (ZeroBased n) where+ type Composed (ZeroBased n) = ZeroBased (MultiValue.Composed n)+ compose (ZeroBased n) = zeroBased (MultiValue.compose n)++instance (MultiValue.Decompose pn) => MultiValue.Decompose (ZeroBased pn) where+ decompose (ZeroBased p) sh =+ MultiValue.decompose p <$> unzipZeroBased sh++instance (Expr.Compose n) => Expr.Compose (ZeroBased n) where+ type Composed (ZeroBased n) = ZeroBased (Expr.Composed n)+ compose (ZeroBased n) = Expr.lift1 zeroBased (Expr.compose n)++instance (Expr.Decompose pn) => Expr.Decompose (ZeroBased pn) where+ decompose (ZeroBased p) = ZeroBased . Expr.decompose p . zeroBasedSize++instance (MultiMem.C n) => MultiMem.C (ZeroBased n) where+ type Struct (ZeroBased n) = MultiMem.Struct n+ decompose = fmap zeroBased . MultiMem.decompose+ compose = MultiMem.compose . zeroBasedSize++{- |+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.++So maybe, we would better have type Index (ZeroBased Word64) = Int64.+This is not possible.+Maybe we need an additional ZeroBased type for unsigned array sizes.+-}+instance+ (Integral n, ToSize n, MultiValue.Comparison n) => C (ZeroBased n) where+ intersectCode sha shb =+ zeroBased <$> MultiValue.min (zeroBasedSize sha) (zeroBasedSize shb)+ size = toSize . zeroBasedSize+ sizeOffset sh = Monad.lift2 (,) (toSize $ zeroBasedSize sh) (return toSize)+ iterator sh =+ IterMV.take (zeroBasedSize sh) $+ Iter.iterate MultiValue.inc MultiValue.zero++instance+ (Integral n, ToSize n, MultiValue.Comparison n) =>+ Sequence (ZeroBased n) where+ sequenceShapeFromIndex = return . zeroBased+++singletonRange :: n -> Range n+singletonRange n = Range n 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)+++rangeFrom :: (Expr.Value val) => val (Range n) -> val n+rangeFrom = Expr.lift1 $ Shape.rangeFrom . unzipRange++rangeTo :: (Expr.Value val) => val (Range n) -> val n+rangeTo = Expr.lift1 $ Shape.rangeTo . unzipRange++range :: (Expr.Value val) => val n -> val n -> val (Range n)+range =+ Expr.lift2 $+ \(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 (Ix n, ToSize n, MultiValue.Comparison n) => C (Range n) where+ intersectCode =+ MultiValue.modifyF2 (singletonRange atom) (singletonRange atom) $+ \(Range fromN toN) (Range fromM toM) ->+ Monad.lift2 Range (MultiValue.max fromN fromM) (MultiValue.min toN toM)+ size = rangeSize . unzipRange+ sizeOffset rngValue =+ case unzipRange rngValue of+ rng@(Range from _to) ->+ Monad.lift2 (,) (rangeSize rng)+ (return $ \i -> 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+++singletonShifted :: n -> Shifted n+singletonShifted n = Shifted n n+++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)+++shiftedOffset :: (Expr.Value val) => val (Shifted n) -> val n+shiftedOffset = Expr.lift1 $ Shape.shiftedOffset . unzipShifted++shiftedSize :: (Expr.Value val) => val (Shifted n) -> val n+shiftedSize = Expr.lift1 $ Shape.shiftedSize . unzipShifted++shifted :: (Expr.Value val) => val n -> val n -> val (Shifted n)+shifted =+ Expr.lift2 $+ \(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 start len) =+ zipShifted (MultiValue.cons start) (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 start len) =+ zipShifted (MultiValue.compose start) (MultiValue.compose len)++instance (MultiValue.Decompose pn) => MultiValue.Decompose (Shifted pn) where+ decompose (Shifted pstart plen) rng =+ case unzipShifted rng of+ Shifted start len ->+ Shifted+ (MultiValue.decompose pstart start)+ (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+ intersectCode =+ MultiValue.modifyF2 (singletonShifted atom) (singletonShifted atom) $+ \(Shifted startN lenN) (Shifted startM lenM) -> do+ start <- MultiValue.max startN startM+ endN <- MultiValue.add startN lenN+ endM <- MultiValue.add startM lenM+ end <- MultiValue.min endN endM+ Shifted start <$> MultiValue.sub end start+ size = toSize . shiftedSize+ sizeOffset shapeValue =+ case unzipShifted shapeValue of+ Shifted start len ->+ Monad.lift2 (,) (toSize len)+ (return $ \i -> toSize =<< MultiValue.sub i start)+ 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+ 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)+ size nm =+ case MultiValue.unzip nm of+ (n,m) -> Monad.liftJoin2 A.mul (size n) (size m)+ sizeOffset nm =+ case MultiValue.unzip nm of+ (n,m) -> do+ (ns, iOffset) <- sizeOffset n+ (ms, jOffset) <- sizeOffset m+ sz <- A.mul ns ms+ return+ (sz,+ \ij ->+ case MultiValue.unzip ij of+ (i,j) -> do+ il <- iOffset i+ jl <- jOffset j+ 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+ 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)+ size nml =+ case MultiValue.unzip3 nml of+ (n,m,l) ->+ Monad.liftJoin2 A.mul (size n) $+ Monad.liftJoin2 A.mul (size m) (size l)+ sizeOffset nml =+ case MultiValue.unzip3 nml of+ (n,m,l) -> do+ (ns, iOffset) <- sizeOffset n+ (ms, jOffset) <- sizeOffset m+ (ls, kOffset) <- sizeOffset l+ sz <- A.mul ns =<< A.mul ms ls+ return+ (sz,+ \ijk ->+ case MultiValue.unzip3 ijk of+ (i,j,k) -> do+ il <- iOffset i+ jl <- jOffset j+ kl <- kOffset k+ A.add kl =<< A.mul ls =<< A.add jl =<< A.mul ms il)+ 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/Shape/Cubic.hs view
@@ -15,7 +15,7 @@ constant, paramWith, tunnel,- flattenIndex,+ offsetCode, peek, poke, computeSize,@@ -34,13 +34,16 @@ storeMultiValue, ) where -import qualified Data.Array.Knead.Shape.Nested as Shape+import qualified Data.Array.Knead.Shape 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 Data.Array.Comfort.Shape as ComfortShape+import Data.Array.Comfort.Shape (ZeroBased(ZeroBased))+ 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@@ -87,7 +90,8 @@ (runSwitchInt $ Index.switchSingle (SwitchInt cons0)) -newtype Op2 tag sh = Op2 {runOp2 :: Exp (T tag sh) -> Exp (T tag sh) -> Exp (T tag sh)}+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 =@@ -104,7 +108,8 @@ _value = Expr.lift0 . MultiValue.cons -newtype MakeValue val tag sh = MakeValue {runMakeValue :: T tag sh -> val (T tag sh)}+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 =@@ -285,16 +290,57 @@ addPhis = addPhis phis = phis -instance (tag ~ ShapeTag, C sh) => Shape.C (T tag sh) where- type Index (T tag sh) = Index sh+instance (tag ~ ShapeTag, C sh) => ComfortShape.C (T tag sh) where size = fromIntegral . size . decons- sizeCode = computeSize++instance (tag ~ ShapeTag, C sh) => ComfortShape.Indexed (T tag sh) where+ type Index (T tag sh) = Index sh+ indices (Cons ix) = map index $ indices ix+ inBounds (Cons sh) (Cons ix) = inBounds sh ix+ offset (Cons sh) (Cons ix) = offset sh ix+++newtype Indices sh = Indices {runIndices :: sh -> [sh]}++indices :: (C sh) => sh -> [sh]+indices =+ runIndices $+ switchInt+ (Indices $ \Z -> [Z])+ (Indices $ \(t :. Index.Int h) ->+ liftM2 (:.) (indices t)+ (map Index.Int $ ComfortShape.indices $ ZeroBased h))++newtype InBounds sh = InBounds {runInBounds :: sh -> sh -> Bool}++inBounds :: (C sh) => sh -> sh -> Bool+inBounds =+ runInBounds $+ switchInt+ (InBounds $ \Z Z -> True)+ (InBounds $ \(sh :. Index.Int s) (ix :. Index.Int i) ->+ inBounds sh ix && ComfortShape.inBounds (ZeroBased s) i)++newtype Offset sh = Offset {runOffset :: sh -> sh -> Int}++offset :: (C sh) => sh -> sh -> Int+offset =+ runOffset $+ switchInt+ (Offset $ \Z Z -> 0)+ (Offset $ \(sh :. Index.Int s) (ix :. Index.Int i) ->+ offset sh ix * fromIntegral s + fromIntegral i)++++instance (tag ~ ShapeTag, C sh) => Shape.C (T tag sh) where+ size = computeSize intersectCode = Expr.unliftM2 intersect- flattenIndexRec sh ix =- -- a joint implementation would not be more efficient+ sizeOffset sh =+ -- would a joint implementation be more efficient? liftM2 (,) (computeSize sh)- (flattenIndex sh ix)+ (return $ offsetCode sh) iterator = iterator loop = loop @@ -327,25 +373,25 @@ StructFieldsProp -> store x =<< castPtrValue ptr -newtype FlattenIndex r sh =- FlattenIndex {- runFlattenIndex ::+newtype OffsetCode r sh =+ OffsetCode {+ runOffsetCode :: MultiValue.T (Shape sh) -> MultiValue.T (Index sh) -> LLVM.CodeGenFunction r (LLVM.Value Shape.Size) } -flattenIndex ::+offsetCode :: (C sh) => MultiValue.T (Shape sh) -> MultiValue.T (Index sh) -> LLVM.CodeGenFunction r (LLVM.Value Shape.Size)-flattenIndex =- runFlattenIndex $+offsetCode =+ runOffsetCode $ switchInt- (FlattenIndex $ \_zerosh _zeroix -> return A.zero)- (FlattenIndex $+ (OffsetCode $ \_zerosh _zeroix -> return A.zero)+ (OffsetCode $ switchR $ \sh (MultiValue.Cons s) -> switchR $ \ix (MultiValue.Cons i) ->- A.add i =<< A.mul s =<< flattenIndex sh ix)+ A.add i =<< A.mul s =<< offsetCode sh ix) newtype Rank sh = Rank {runRank :: sh -> Int}@@ -432,10 +478,7 @@ store sh =<< A.advanceArrayElementPtr ptr) -newtype Size sh =- Size {- runSize :: sh -> Shape.Size- }+newtype Size sh = Size {runSize :: sh -> Shape.Size} size :: (C sh) => sh -> Shape.Size size =
− src/Data/Array/Knead/Shape/Nested.hs
@@ -1,539 +0,0 @@-{-# 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
@@ -22,7 +22,7 @@ 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.Shape as Shape import qualified Data.Array.Knead.Expression as Expr import Data.Array.Knead.Expression (Exp, unExp, ) import Data.Array.Knead.Shape.Cubic ((#:.), (:.)((:.)), )@@ -74,7 +74,8 @@ (Val (Linear.Index (sh :. IndexInt.Int)) -> Code r a) -> (Val (Linear.Index sh) -> Code r a) fold1CodeLinear f nc code ix =- Core.fold1Code f (IndexInt.decons nc)+ Core.fold1Code f+ (Expr.lift1 (MultiValue.compose . Shape.ZeroBased) $ IndexInt.decons nc) (\j -> code (ix #:. IndexInt.cons j)) fold ::
src/Data/Array/Knead/Simple/Physical.hs view
@@ -2,7 +2,8 @@ {-# LANGUAGE Rank2Types #-} {-# LANGUAGE ForeignFunctionInterface #-} module Data.Array.Knead.Simple.Physical (- Array(Array, shape, buffer), -- data constructor intended for PhysicalParameterized+ Array,+ shape, toList, fromList, vectorFromList,@@ -17,12 +18,17 @@ import qualified Data.Array.Knead.Simple.PhysicalPrivate as Priv import qualified Data.Array.Knead.Simple.Private as Sym-import qualified Data.Array.Knead.Shape.Nested as Shape+import qualified Data.Array.Knead.Shape 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 (getElementPtr, compile, ) +import qualified Data.Array.Comfort.Storable.Mutable.Unchecked as MutArray+import qualified Data.Array.Comfort.Storable.Unchecked as Array+import qualified Data.Array.Comfort.Shape as ComfortShape+import Data.Array.Comfort.Storable.Unchecked (Array(Array))+ import qualified LLVM.Extra.Multi.Value.Memory as MultiValueMemory import qualified LLVM.Extra.Multi.Value as MultiValue import qualified LLVM.Extra.Arithmetic as A@@ -31,52 +37,36 @@ import qualified LLVM.Core as LLVM -import Foreign.Marshal.Array (pokeArray, peekArray, ) import Foreign.Marshal.Alloc (alloca, ) import Foreign.Storable (Storable, peek, )-import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, mallocForeignPtrArray, )+import Foreign.ForeignPtr (withForeignPtr, mallocForeignPtrArray, ) import Foreign.Ptr (FunPtr, Ptr, ) -import Control.Monad.HT (void, )+import Control.Monad.HT (void, (<=<), ) import Control.Applicative (liftA2, (<$>), ) import Prelude hiding (scanl1, ) -data Array sh a =- Array {- shape :: sh,- buffer :: ForeignPtr a- }-+shape :: Array sh a -> sh+shape = Array.shape toList :: (Shape.C sh, Storable a) => Array sh a -> IO [a]-toList (Array sh fptr) =- withForeignPtr fptr $ peekArray (Shape.size sh)+toList = MutArray.toList <=< MutArray.unsafeThaw fromList :: (Shape.C sh, Storable a) => sh -> [a] -> IO (Array sh a)-fromList sh xs = do- let size = Shape.size sh- fptr <- mallocForeignPtrArray size- withForeignPtr fptr $- \ptr ->- pokeArray ptr $- take size $- xs ++ repeat (error "Array.Knead.Physical.fromList: list too short for shape")- return (Array sh fptr)+fromList sh = MutArray.unsafeFreeze <=< MutArray.fromList sh vectorFromList ::- (Shape.C sh, Num sh, Storable a) =>- [a] -> IO (Array sh a)-vectorFromList xs = do- let size = length xs- fptr <- mallocForeignPtrArray size- withForeignPtr fptr $ flip pokeArray xs- return (Array (fromIntegral size) fptr)+ (Num n, Storable a) =>+ [a] -> IO (Array (ComfortShape.ZeroBased n) a)+vectorFromList xs =+ Array.mapShape (\(Shape.ZeroBased n) -> Shape.ZeroBased $ fromIntegral n) <$>+ (MutArray.unsafeFreeze =<< MutArray.vectorFromList xs) {- |@@ -122,7 +112,7 @@ (Code.createFunction callShaper "shape" $ \ptr -> do sh <- unExp esh MultiValueMemory.store sh ptr- Shape.sizeCode sh >>= LLVM.ret)+ Shape.size sh >>= LLVM.ret) (Code.createFunction callRenderer "fill" (\paramPtr arrayPtr -> code paramPtr arrayPtr >> LLVM.ret ())) let lshptr = MultiValueMemory.castStructPtr shptr
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.Shape.Nested as Shape+import qualified Data.Array.Knead.Shape as Shape import qualified Data.Array.Knead.Expression as Expr import Data.Array.Knead.Expression (Exp, unExp) import Data.Array.Knead.Code (getElementPtr)
src/Data/Array/Knead/Simple/Private.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE TypeFamilies #-} module Data.Array.Knead.Simple.Private where -import qualified Data.Array.Knead.Shape.Nested as Shape+import qualified Data.Array.Knead.Shape as Shape import qualified Data.Array.Knead.Expression as Expr import Data.Array.Knead.Expression (Exp(Exp), )
src/Data/Array/Knead/Simple/ShapeDependent.hs view
@@ -4,7 +4,7 @@ import qualified Data.Array.Knead.Simple.Private as Core import Data.Array.Knead.Simple.Private (Array(Array), ) -import qualified Data.Array.Knead.Shape.Nested as Shape+import qualified Data.Array.Knead.Shape as Shape import qualified Data.Array.Knead.Expression as Expr import Data.Array.Knead.Expression (Exp, )
src/Data/Array/Knead/Simple/Slice.hs view
@@ -70,7 +70,7 @@ import qualified Data.Array.Knead.Simple.Private as Core import qualified Data.Array.Knead.Shape.Cubic as Linear-import qualified Data.Array.Knead.Shape.Nested as Shape+import qualified Data.Array.Knead.Shape as Shape import qualified Data.Array.Knead.Expression as Expr import Data.Array.Knead.Shape.Cubic ((#:.), (:.)((:.)), ) import Data.Array.Knead.Expression (Exp, )
src/Data/Array/Knead/Simple/Symbolic.hs view
@@ -31,7 +31,7 @@ import qualified Data.Array.Knead.Simple.Private as Core import Data.Array.Knead.Simple.Private (Array, shape, gather, ) -import qualified Data.Array.Knead.Shape.Nested as Shape+import qualified Data.Array.Knead.Shape as Shape import qualified Data.Array.Knead.Expression as Expr import Data.Array.Knead.Expression (Exp, )