accelerate 0.6.0.0 → 0.7.1.0
raw patch · 46 files changed
+4511/−323 lines, 46 filesdep +binarydep +bytestringdep +containersdep ~basePVP ok
version bump matches the API change (PVP)
Dependencies added: binary, bytestring, containers, cuda, directory, fclabels, filepath, language-c, llvm, monads-fd, transformers, unix
Dependency ranges changed: base
API changes (from Hackage documentation)
- Data.Array.Accelerate: scan :: (Elem a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Vector a) -> (Acc (Vector a), Acc (Scalar a))
+ Data.Array.Accelerate: bit :: (Elem t, IsIntegral t) => Exp Int -> Exp t
+ Data.Array.Accelerate: clearBit :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp t
+ Data.Array.Accelerate: complementBit :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp t
+ Data.Array.Accelerate: curry :: (Elem a, Elem b) => (Exp (a, b) -> Exp c) -> Exp a -> Exp b -> Exp c
+ Data.Array.Accelerate: fst :: (Elem a, Elem b) => Exp (a, b) -> Exp a
+ Data.Array.Accelerate: intToFloat :: Exp Int -> Exp Float
+ Data.Array.Accelerate: rotate :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp t
+ Data.Array.Accelerate: rotateL :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp t
+ Data.Array.Accelerate: rotateR :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp t
+ Data.Array.Accelerate: roundFloatToInt :: Exp Float -> Exp Int
+ Data.Array.Accelerate: scanl :: (Elem a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Vector a) -> (Acc (Vector a), Acc (Scalar a))
+ Data.Array.Accelerate: scanr :: (Elem a) => (Exp a -> Exp a -> Exp a) -> Exp a -> Acc (Vector a) -> (Acc (Vector a), Acc (Scalar a))
+ Data.Array.Accelerate: setBit :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp t
+ Data.Array.Accelerate: shift :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp t
+ Data.Array.Accelerate: shiftL :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp t
+ Data.Array.Accelerate: shiftR :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp t
+ Data.Array.Accelerate: snd :: (Elem a, Elem b) => Exp (a, b) -> Exp b
+ Data.Array.Accelerate: testBit :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp Bool
+ Data.Array.Accelerate: truncateFloatToInt :: Exp Float -> Exp Int
+ Data.Array.Accelerate: uncurry :: (Elem a, Elem b) => (Exp a -> Exp b -> Exp c) -> Exp (a, b) -> Exp c
- Data.Array.Accelerate: shape :: (Ix dim) => Acc (Array dim e) -> Exp dim
+ Data.Array.Accelerate: shape :: (Ix dim, Elem dim) => Acc (Array dim e) -> Exp dim
Files
- Data/Array/Accelerate/AST.hs +64/−17
- Data/Array/Accelerate/Analysis/Type.hs +96/−0
- Data/Array/Accelerate/Array/Data.hs +157/−30
- Data/Array/Accelerate/Array/Representation.hs +0/−3
- Data/Array/Accelerate/Array/Sugar.hs +58/−58
- Data/Array/Accelerate/CUDA.hs +39/−0
- Data/Array/Accelerate/CUDA/Analysis/Hash.hs +71/−0
- Data/Array/Accelerate/CUDA/Analysis/Launch.hs +74/−0
- Data/Array/Accelerate/CUDA/Array/Data.hs +345/−0
- Data/Array/Accelerate/CUDA/Array/Device.hs +42/−0
- Data/Array/Accelerate/CUDA/CodeGen.hs +475/−0
- Data/Array/Accelerate/CUDA/CodeGen/Data.hs +34/−0
- Data/Array/Accelerate/CUDA/CodeGen/Skeleton.hs +150/−0
- Data/Array/Accelerate/CUDA/CodeGen/Tuple.hs +87/−0
- Data/Array/Accelerate/CUDA/CodeGen/Util.hs +102/−0
- Data/Array/Accelerate/CUDA/Compile.hs +177/−0
- Data/Array/Accelerate/CUDA/Execute.hs +381/−0
- Data/Array/Accelerate/CUDA/State.hs +174/−0
- Data/Array/Accelerate/Interpreter.hs +149/−64
- Data/Array/Accelerate/Language.hs +105/−31
- Data/Array/Accelerate/Pretty.hs +58/−38
- Data/Array/Accelerate/Smart.hs +91/−11
- Data/Array/Accelerate/Tuple.hs +2/−2
- Data/Array/Accelerate/Type.hs +15/−3
- INSTALL +13/−7
- accelerate.cabal +140/−50
- cubits/accelerate_cuda_extras.h +207/−0
- cubits/accelerate_cuda_utils.h +136/−0
- cubits/backpermute.inl +32/−0
- cubits/fold.inl +92/−0
- cubits/map.inl +29/−0
- cubits/permute.inl +40/−0
- cubits/thrust/scan_safe.inl +289/−0
- cubits/zipWith.inl +30/−0
- examples/rasterize/RasterizeAcc.hs +244/−0
- examples/rasterize/rasterize-test1.txt +4/−0
- examples/rasterize/rasterize-test2.txt +4/−0
- examples/rasterize/rasterize-test3.txt +4/−0
- examples/rasterize/rasterize-test4.txt +4/−0
- examples/rasterize/rasterize.hs +111/−0
- examples/simple/Filter.hs +4/−2
- examples/simple/Main.hs +130/−4
- examples/simple/Makefile +4/−1
- examples/simple/SAXPY.hs +2/−2
- examples/simple/Square.hs +23/−0
- examples/simple/Sum.hs +23/−0
Data/Array/Accelerate/AST.hs view
@@ -65,10 +65,13 @@ -- * Typed de Bruijn indices Idx(..),- ++ -- * Valuation environment+ Val(..), prj,+ -- * Accelerated array expressions OpenAcc(..), Acc,- + -- * Scalar expressions OpenFun(..), Fun, OpenExp(..), Exp, PrimConst(..), PrimFun(..) @@ -92,6 +95,24 @@ SuccIdx :: Idx env t -> Idx (env, s) t +-- Environments+-- ------------++-- Valuation for an environment+--+data Val env where+ Empty :: Val ()+ Push :: Val env -> t -> Val (env, t)++-- Projection of a value from a valuation using a de Bruijn index+--+prj :: Idx env t -> Val env -> t+prj ZeroIdx (Push _ v) = v+prj (SuccIdx idx) (Push val _) = prj idx val+prj _ _ =+ error "Data.Array.Accelerate: prj: inconsistent valuation"++ -- Array expressions -- ----------------- @@ -133,7 +154,8 @@ -> OpenAcc aenv (Array dim' e') -- Variable bound by a 'Let', represented by a de Bruijn index - Avar :: Idx aenv (Array dim e)+ Avar :: Elem e+ => Idx aenv (Array dim e) -> OpenAcc aenv (Array dim e) -- Array inlet (triggers async host->device transfer if necessary)@@ -212,12 +234,18 @@ -- function and its neutral element; produces a rightmost fold value and a -- linear of the same shape (the fold value would be the rightmost element -- in a scan, as opposed to a prescan)- Scan :: Fun aenv (e -> e -> e) -- combination function+ Scanl :: Fun aenv (e -> e -> e) -- combination function -> Exp aenv e -- default value -> OpenAcc aenv (Vector e) -- linear array -> OpenAcc aenv (Vector e, Scalar e) -- FIXME: generalised multi-dimensional scan? And/or a generalised mapScan? + -- Right-to-left prescan of a linear array+ Scanr :: Fun aenv (e -> e -> e) -- combination function+ -> Exp aenv e -- default value+ -> OpenAcc aenv (Vector e) -- linear array+ -> OpenAcc aenv (Vector e, Scalar e)+ -- Generalised forward permutation is characterised by a permutation -- function that determines for each element of the source array where it -- should go in the target; the permutation can be between arrays of varying@@ -282,7 +310,7 @@ => ElemRepr t -> OpenExp env aenv t - -- Tuples+ -- Tuples Tuple :: (Elem t, IsTuple t) => Tuple (OpenExp env aenv) (TupleRepr t) -> OpenExp env aenv t@@ -315,7 +343,8 @@ -- Array shape -- the array expression cannot contain any free scalar variables- Shape :: OpenAcc aenv (Array dim e) + Shape :: Elem dim+ => OpenAcc aenv (Array dim e) -> OpenExp env aenv dim -- |Expression without free scalar variables@@ -346,19 +375,37 @@ PrimSig :: NumType a -> PrimFun (a -> a) -- operators from Integral & Bits- PrimQuot :: IntegralType a -> PrimFun ((a, a) -> a)- PrimRem :: IntegralType a -> PrimFun ((a, a) -> a)- PrimIDiv :: IntegralType a -> PrimFun ((a, a) -> a)- PrimMod :: IntegralType a -> PrimFun ((a, a) -> a)- PrimBAnd :: IntegralType a -> PrimFun ((a, a) -> a)- PrimBOr :: IntegralType a -> PrimFun ((a, a) -> a)- PrimBXor :: IntegralType a -> PrimFun ((a, a) -> a)- PrimBNot :: IntegralType a -> PrimFun (a -> a)- -- FIXME: add shifts+ PrimQuot :: IntegralType a -> PrimFun ((a, a) -> a)+ PrimRem :: IntegralType a -> PrimFun ((a, a) -> a)+ PrimIDiv :: IntegralType a -> PrimFun ((a, a) -> a)+ PrimMod :: IntegralType a -> PrimFun ((a, a) -> a)+ PrimBAnd :: IntegralType a -> PrimFun ((a, a) -> a)+ PrimBOr :: IntegralType a -> PrimFun ((a, a) -> a)+ PrimBXor :: IntegralType a -> PrimFun ((a, a) -> a)+ PrimBNot :: IntegralType a -> PrimFun (a -> a)+ PrimBShiftL :: IntegralType a -> PrimFun ((a, Int) -> a)+ PrimBShiftR :: IntegralType a -> PrimFun ((a, Int) -> a)+ PrimBRotateL :: IntegralType a -> PrimFun ((a, Int) -> a)+ PrimBRotateR :: IntegralType a -> PrimFun ((a, Int) -> a) -- operators from Fractional, Floating, RealFrac & RealFloat- PrimFDiv :: FloatingType a -> PrimFun ((a, a) -> a)- PrimRecip :: FloatingType a -> PrimFun (a -> a)+ + PrimFDiv :: FloatingType a -> PrimFun ((a, a) -> a)+ PrimRecip :: FloatingType a -> PrimFun (a -> a)+ PrimSin :: FloatingType a -> PrimFun (a -> a)+ PrimCos :: FloatingType a -> PrimFun (a -> a)+ PrimTan :: FloatingType a -> PrimFun (a -> a)+ PrimAsin :: FloatingType a -> PrimFun (a -> a)+ PrimAcos :: FloatingType a -> PrimFun (a -> a)+ PrimAtan :: FloatingType a -> PrimFun (a -> a)+ PrimAsinh :: FloatingType a -> PrimFun (a -> a)+ PrimAcosh :: FloatingType a -> PrimFun (a -> a)+ PrimAtanh :: FloatingType a -> PrimFun (a -> a)+ PrimExpFloating :: FloatingType a -> PrimFun (a -> a)+ PrimSqrt :: FloatingType a -> PrimFun (a -> a)+ PrimLog :: FloatingType a -> PrimFun (a -> a)+ PrimFPow :: FloatingType a -> PrimFun ((a,a) -> a)+ PrimLogBase :: FloatingType a -> PrimFun ((a,a) -> a) -- FIXME: add operations from Floating, RealFrac & RealFloat -- relational and equality operators
+ Data/Array/Accelerate/Analysis/Type.hs view
@@ -0,0 +1,96 @@+{-# LANGUAGE ScopedTypeVariables, GADTs, TypeFamilies, PatternGuards #-}++-- |Embedded array processing language: type analysis+--+-- Copyright (c) 2009 Manuel M T Chakravarty, Gabriele Keller, Sean Lee+--+-- License: BSD3+--+--- Description ---------------------------------------------------------------+--+-- The Accelerate AST does not explicitly store much type information. Most of+-- it is only indirectly through type class constraints -especially, Elem+-- constraints- available. This module provides functions that reify that +-- type information in the form of a 'TupleType' value. This is, for example,+-- needed to emit type information in a backend.++module Data.Array.Accelerate.Analysis.Type (++ -- * Query AST types+ accType, accType2, expType, sizeOf+ +) where+ +-- friends+import Data.Array.Accelerate.Type+import Data.Array.Accelerate.Tuple+import Data.Array.Accelerate.Array.Sugar+import Data.Array.Accelerate.AST++-- neighbours+import qualified Foreign.Storable as F+++-- Determine the type of an expressions+-- ------------------------------------++-- |Reify the element type of the result of an array computation.+--+accType :: forall aenv dim e.+ OpenAcc aenv (Array dim e) -> TupleType (ElemRepr e)+accType (Let _ acc) = accType acc+accType (Let2 _ acc) = accType acc+accType (Avar _) = elemType (undefined::e)+accType (Use arr) = arrayType arr+accType (Unit _) = elemType (undefined::e)+accType (Reshape _ acc) = accType acc+accType (Replicate _ _ acc) = accType acc+accType (Index _ acc _) = accType acc+accType (Map _ _) = elemType (undefined::e)+accType (ZipWith _ _ _) = elemType (undefined::e)+accType (Fold _ _ acc) = accType acc+accType (FoldSeg _ _ acc _) = accType acc+accType (Permute _ _ _ acc) = accType acc+accType (Backpermute _ _ acc) = accType acc++-- |Reify the element types of the results of an array computation that yields+-- two arrays.+--+accType2 :: OpenAcc aenv (Array dim1 e1, Array dim2 e2)+ -> (TupleType (ElemRepr e1), TupleType (ElemRepr e2))+accType2 (Scanl _ e acc) = (accType acc, expType e)+accType2 (Scanr _ e acc) = (accType acc, expType e)++-- |Reify the result type of a scalar expression.+--+expType :: forall aenv env t. OpenExp aenv env t -> TupleType (ElemRepr t)+expType (Var _) = elemType (undefined::t)+expType (Const _) = elemType (undefined::t)+expType (Tuple _) = elemType (undefined::t)+expType (Prj idx _) = tupleIdxType idx+expType (Cond _ t _) = expType t+expType (PrimConst _) = elemType (undefined::t)+expType (PrimApp _ _) = elemType (undefined::t)+expType (IndexScalar acc _) = accType acc+expType (Shape _) = elemType (undefined::t)++-- |Reify the result type of a tuple projection.+--+tupleIdxType :: forall t e. TupleIdx t e -> TupleType (ElemRepr e)+tupleIdxType ZeroTupIdx = elemType (undefined::e)+tupleIdxType (SuccTupIdx idx) = tupleIdxType idx+++-- |Size of a tuple type, in bytes+--+sizeOf :: TupleType a -> Int+sizeOf UnitTuple = 0+sizeOf (PairTuple a b) = sizeOf a + sizeOf b++sizeOf (SingleTuple (NumScalarType (IntegralNumType t)))+ | IntegralDict <- integralDict t = F.sizeOf $ (undefined :: IntegralType a -> a) t+sizeOf (SingleTuple (NumScalarType (FloatingNumType t)))+ | FloatingDict <- floatingDict t = F.sizeOf $ (undefined :: FloatingType a -> a) t+sizeOf (SingleTuple (NonNumScalarType t))+ | NonNumDict <- nonNumDict t = F.sizeOf $ (undefined :: NonNumType a -> a) t+
Data/Array/Accelerate/Array/Data.hs view
@@ -1,34 +1,52 @@ {-# LANGUAGE GADTs, TypeFamilies, FlexibleContexts, FlexibleInstances #-}-{-# LANGUAGE RankNTypes #-}---- |Embedded array processing language: array data layout for linear arrays------ Copyright (c) 2009 Manuel M T Chakravarty, Gabriele Keller, Sean Lee------ License: BSD3+{-# LANGUAGE RankNTypes, MagicHash, UnboxedTuples #-}+-- |+-- Module : Data.Array.Accelerate.Array.Data+-- Copyright : [2009..2010] Manuel M T Chakravarty, Gabriele Keller, Sean Lee+-- License : BSD3 ------ Description ---------------------------------------------------------------+-- Maintainer : Manuel M T Chakravarty <chak@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions) --+-- This module fixes the concrete representation of Accelerate arrays. We+-- allocate all arrays using pinned memory to enable safe direct-access by+-- non-Haskell code in multi-threaded code. In particular, we can safely pass+-- pointers to an array's payload to foreign code. module Data.Array.Accelerate.Array.Data ( -- * Array operations and representations- ArrayElem(..), ArrayData, MutableArrayData, runArrayData+ ArrayElem(..), ArrayData, MutableArrayData, runArrayData,+ + -- * Array tuple operations+ fstArrayData, sndArrayData, pairArrayData ) where -- standard libraries+import Foreign (Ptr)+import GHC.Base (Int(..))+import GHC.Prim (newPinnedByteArray#, byteArrayContents#,+ unsafeFreezeByteArray#, Int#, (*#))+import GHC.Ptr (Ptr(Ptr))+import GHC.ST (ST(ST)) import Control.Monad import Control.Monad.ST import qualified Data.Array.IArray as IArray-import qualified Data.Array.MArray as MArray+import qualified Data.Array.MArray as MArray hiding (newArray) import Data.Array.ST (STUArray) import Data.Array.Unboxed (UArray)+import Data.Array.Base (UArray(UArray), STUArray(STUArray), bOOL_SCALE,+ wORD_SCALE, fLOAT_SCALE, dOUBLE_SCALE) -- friends import Data.Array.Accelerate.Type +-- Array representation+-- --------------------+ -- |Immutable array representation -- type ArrayData e = GArrayData (UArray Int) e@@ -72,93 +90,134 @@ data instance GArrayData ba (a, b) = AD_Pair (GArrayData ba a) (GArrayData ba b) ++-- Array operations+-- ----------------+ class ArrayElem e where- indexArrayData :: ArrayData e -> Int -> e+ type ArrayPtrs e --- newArrayData :: Int -> ST s (MutableArrayData s e)- readArrayData :: MutableArrayData s e -> Int -> ST s e- writeArrayData :: MutableArrayData s e -> Int -> e -> ST s ()- unsafeFreezeArrayData :: MutableArrayData s e -> ST s (ArrayData e)+ indexArrayData :: ArrayData e -> Int -> e+ ptrsOfArrayData :: ArrayData e -> ArrayPtrs e+ --+ newArrayData :: Int -> ST s (MutableArrayData s e)+ readArrayData :: MutableArrayData s e -> Int -> ST s e+ writeArrayData :: MutableArrayData s e -> Int -> e -> ST s ()+ unsafeFreezeArrayData :: MutableArrayData s e -> ST s (ArrayData e)+ ptrsOfMutableArrayData :: MutableArrayData s e -> ST s (ArrayPtrs e) instance ArrayElem () where+ type ArrayPtrs () = () indexArrayData AD_Unit i = i `seq` ()- newArrayData _ = return AD_Unit+ ptrsOfArrayData AD_Unit = ()+ newArrayData size = size `seq` return AD_Unit readArrayData AD_Unit i = i `seq` return () writeArrayData AD_Unit i () = i `seq` return () unsafeFreezeArrayData AD_Unit = return AD_Unit+ ptrsOfMutableArrayData AD_Unit = return () instance ArrayElem Int where+ type ArrayPtrs Int = Ptr Int indexArrayData (AD_Int ba) i = ba IArray.! i- newArrayData size = liftM AD_Int $ MArray.newArray_ (0, size - 1)+ ptrsOfArrayData (AD_Int ba) = uArrayPtr ba+ newArrayData size = liftM AD_Int $ unsafeNewArray_ size wORD_SCALE readArrayData (AD_Int ba) i = MArray.readArray ba i writeArrayData (AD_Int ba) i e = MArray.writeArray ba i e unsafeFreezeArrayData (AD_Int ba) = liftM AD_Int $ MArray.unsafeFreeze ba+ ptrsOfMutableArrayData (AD_Int ba) = sTUArrayPtr ba instance ArrayElem Int8 where+ type ArrayPtrs Int8 = Ptr Int8 indexArrayData (AD_Int8 ba) i = ba IArray.! i- newArrayData size = liftM AD_Int8 $ MArray.newArray_ (0, size - 1)+ ptrsOfArrayData (AD_Int8 ba) = uArrayPtr ba+ newArrayData size = liftM AD_Int8 $ unsafeNewArray_ size (\x -> x) readArrayData (AD_Int8 ba) i = MArray.readArray ba i writeArrayData (AD_Int8 ba) i e = MArray.writeArray ba i e unsafeFreezeArrayData (AD_Int8 ba) = liftM AD_Int8 $ MArray.unsafeFreeze ba+ ptrsOfMutableArrayData (AD_Int8 ba) = sTUArrayPtr ba instance ArrayElem Int16 where+ type ArrayPtrs Int16 = Ptr Int16 indexArrayData (AD_Int16 ba) i = ba IArray.! i- newArrayData size = liftM AD_Int16 $ MArray.newArray_ (0, size - 1)+ ptrsOfArrayData (AD_Int16 ba) = uArrayPtr ba+ newArrayData size = liftM AD_Int16 $ unsafeNewArray_ size (*# 2#) readArrayData (AD_Int16 ba) i = MArray.readArray ba i writeArrayData (AD_Int16 ba) i e = MArray.writeArray ba i e unsafeFreezeArrayData (AD_Int16 ba) = liftM AD_Int16 $ MArray.unsafeFreeze ba+ ptrsOfMutableArrayData (AD_Int16 ba) = sTUArrayPtr ba instance ArrayElem Int32 where+ type ArrayPtrs Int32 = Ptr Int32 indexArrayData (AD_Int32 ba) i = ba IArray.! i- newArrayData size = liftM AD_Int32 $ MArray.newArray_ (0, size - 1)+ ptrsOfArrayData (AD_Int32 ba) = uArrayPtr ba+ newArrayData size = liftM AD_Int32 $ unsafeNewArray_ size (*# 4#) readArrayData (AD_Int32 ba) i = MArray.readArray ba i writeArrayData (AD_Int32 ba) i e = MArray.writeArray ba i e unsafeFreezeArrayData (AD_Int32 ba) = liftM AD_Int32 $ MArray.unsafeFreeze ba+ ptrsOfMutableArrayData (AD_Int32 ba) = sTUArrayPtr ba instance ArrayElem Int64 where+ type ArrayPtrs Int64 = Ptr Int64 indexArrayData (AD_Int64 ba) i = ba IArray.! i- newArrayData size = liftM AD_Int64 $ MArray.newArray_ (0, size - 1)+ ptrsOfArrayData (AD_Int64 ba) = uArrayPtr ba+ newArrayData size = liftM AD_Int64 $ unsafeNewArray_ size (*# 8#) readArrayData (AD_Int64 ba) i = MArray.readArray ba i writeArrayData (AD_Int64 ba) i e = MArray.writeArray ba i e unsafeFreezeArrayData (AD_Int64 ba) = liftM AD_Int64 $ MArray.unsafeFreeze ba+ ptrsOfMutableArrayData (AD_Int64 ba) = sTUArrayPtr ba instance ArrayElem Word where+ type ArrayPtrs Word = Ptr Word indexArrayData (AD_Word ba) i = ba IArray.! i- newArrayData size = liftM AD_Word $ MArray.newArray_ (0, size - 1)+ ptrsOfArrayData (AD_Word ba) = uArrayPtr ba+ newArrayData size = liftM AD_Word $ unsafeNewArray_ size wORD_SCALE readArrayData (AD_Word ba) i = MArray.readArray ba i writeArrayData (AD_Word ba) i e = MArray.writeArray ba i e unsafeFreezeArrayData (AD_Word ba) = liftM AD_Word $ MArray.unsafeFreeze ba+ ptrsOfMutableArrayData (AD_Word ba) = sTUArrayPtr ba instance ArrayElem Word8 where+ type ArrayPtrs Word8 = Ptr Word8 indexArrayData (AD_Word8 ba) i = ba IArray.! i- newArrayData size = liftM AD_Word8 $ MArray.newArray_ (0, size - 1)+ ptrsOfArrayData (AD_Word8 ba) = uArrayPtr ba+ newArrayData size = liftM AD_Word8 $ unsafeNewArray_ size (\x -> x) readArrayData (AD_Word8 ba) i = MArray.readArray ba i writeArrayData (AD_Word8 ba) i e = MArray.writeArray ba i e unsafeFreezeArrayData (AD_Word8 ba) = liftM AD_Word8 $ MArray.unsafeFreeze ba+ ptrsOfMutableArrayData (AD_Word8 ba) = sTUArrayPtr ba instance ArrayElem Word16 where+ type ArrayPtrs Word16 = Ptr Word16 indexArrayData (AD_Word16 ba) i = ba IArray.! i- newArrayData size = liftM AD_Word16 $ MArray.newArray_ (0, size - 1)+ ptrsOfArrayData (AD_Word16 ba) = uArrayPtr ba+ newArrayData size = liftM AD_Word16 $ unsafeNewArray_ size (*# 2#) readArrayData (AD_Word16 ba) i = MArray.readArray ba i writeArrayData (AD_Word16 ba) i e = MArray.writeArray ba i e unsafeFreezeArrayData (AD_Word16 ba) = liftM AD_Word16 $ MArray.unsafeFreeze ba+ ptrsOfMutableArrayData (AD_Word16 ba) = sTUArrayPtr ba instance ArrayElem Word32 where+ type ArrayPtrs Word32 = Ptr Word32 indexArrayData (AD_Word32 ba) i = ba IArray.! i- newArrayData size = liftM AD_Word32 $ MArray.newArray_ (0, size - 1)+ ptrsOfArrayData (AD_Word32 ba) = uArrayPtr ba+ newArrayData size = liftM AD_Word32 $ unsafeNewArray_ size (*# 4#) readArrayData (AD_Word32 ba) i = MArray.readArray ba i writeArrayData (AD_Word32 ba) i e = MArray.writeArray ba i e unsafeFreezeArrayData (AD_Word32 ba) = liftM AD_Word32 $ MArray.unsafeFreeze ba+ ptrsOfMutableArrayData (AD_Word32 ba) = sTUArrayPtr ba instance ArrayElem Word64 where+ type ArrayPtrs Word64 = Ptr Word64 indexArrayData (AD_Word64 ba) i = ba IArray.! i- newArrayData size = liftM AD_Word64 $ MArray.newArray_ (0, size - 1)+ ptrsOfArrayData (AD_Word64 ba) = uArrayPtr ba+ newArrayData size = liftM AD_Word64 $ unsafeNewArray_ size (*# 8#) readArrayData (AD_Word64 ba) i = MArray.readArray ba i writeArrayData (AD_Word64 ba) i e = MArray.writeArray ba i e unsafeFreezeArrayData (AD_Word64 ba) = liftM AD_Word64 $ MArray.unsafeFreeze ba+ ptrsOfMutableArrayData (AD_Word64 ba) = sTUArrayPtr ba -- FIXME: -- CShort@@ -171,37 +230,55 @@ -- CULLong instance ArrayElem Float where+ type ArrayPtrs Float = Ptr Float indexArrayData (AD_Float ba) i = ba IArray.! i- newArrayData size = liftM AD_Float $ MArray.newArray_ (0, size - 1)+ ptrsOfArrayData (AD_Float ba) = uArrayPtr ba+ newArrayData size = liftM AD_Float $ unsafeNewArray_ size fLOAT_SCALE readArrayData (AD_Float ba) i = MArray.readArray ba i writeArrayData (AD_Float ba) i e = MArray.writeArray ba i e unsafeFreezeArrayData (AD_Float ba) = liftM AD_Float $ MArray.unsafeFreeze ba+ ptrsOfMutableArrayData (AD_Float ba) = sTUArrayPtr ba instance ArrayElem Double where+ type ArrayPtrs Double = Ptr Double indexArrayData (AD_Double ba) i = ba IArray.! i- newArrayData size = liftM AD_Double $ MArray.newArray_ (0, size - 1)+ ptrsOfArrayData (AD_Double ba) = uArrayPtr ba+ newArrayData size = liftM AD_Double $ unsafeNewArray_ size dOUBLE_SCALE readArrayData (AD_Double ba) i = MArray.readArray ba i writeArrayData (AD_Double ba) i e = MArray.writeArray ba i e unsafeFreezeArrayData (AD_Double ba) = liftM AD_Double $ MArray.unsafeFreeze ba+ ptrsOfMutableArrayData (AD_Double ba) = sTUArrayPtr ba -- FIXME: -- CFloat -- CDouble instance ArrayElem Bool where+ type ArrayPtrs Bool = Ptr Word8 indexArrayData (AD_Bool ba) i = ba IArray.! i- newArrayData size = liftM AD_Bool $ MArray.newArray_ (0, size - 1)+-- ptrsOfArrayData (AD_Bool ba) = uArrayPtr ba???currently wrong+-- Unboxed Bool arrays are stored as bit vectors, which is unsuitable+-- for parallel processing (might be useful with sequential LLVM code though)+-- - Do we want to represent 'Array sh Bool' differently or do we want to+-- copy the array on marshaling (but then we also have to copy back+-- results of the same type)+ newArrayData size = liftM AD_Bool $ unsafeNewArray_ size bOOL_SCALE readArrayData (AD_Bool ba) i = MArray.readArray ba i writeArrayData (AD_Bool ba) i e = MArray.writeArray ba i e unsafeFreezeArrayData (AD_Bool ba) = liftM AD_Bool $ MArray.unsafeFreeze ba+-- ptrsOfMutableArrayData (AD_Bool ba) = sTUArrayPtr ba???+-- see ptrsOfArrayData instance ArrayElem Char where+-- type ArrayPtrs Char = ???unicode??? indexArrayData (AD_Char ba) i = ba IArray.! i- newArrayData size = liftM AD_Char $ MArray.newArray_ (0, size - 1)+-- ptrsOfArrayData (AD_Char ba) = ???+ newArrayData size = liftM AD_Char $ unsafeNewArray_ size (*# 4#) readArrayData (AD_Char ba) i = MArray.readArray ba i writeArrayData (AD_Char ba) i e = MArray.writeArray ba i e unsafeFreezeArrayData (AD_Char ba) = liftM AD_Char $ MArray.unsafeFreeze ba+-- ptrsOfMutableArrayData (AD_Char ba) = ??? -- FIXME: -- CChar@@ -209,7 +286,9 @@ -- CUChar instance (ArrayElem a, ArrayElem b) => ArrayElem (a, b) where+ type ArrayPtrs (a, b) = (ArrayPtrs a, ArrayPtrs b) indexArrayData (AD_Pair a b) i = (indexArrayData a i, indexArrayData b i)+ ptrsOfArrayData (AD_Pair a b) = (ptrsOfArrayData a, ptrsOfArrayData b) newArrayData size = do a <- newArrayData size@@ -229,6 +308,11 @@ a' <- unsafeFreezeArrayData a b' <- unsafeFreezeArrayData b return $ AD_Pair a' b'+ ptrsOfMutableArrayData (AD_Pair a b) + = do+ aptr <- ptrsOfMutableArrayData a+ bptr <- ptrsOfMutableArrayData b+ return (aptr, bptr) -- |Safe combination of creating and fast freezing of array data. --@@ -238,3 +322,46 @@ (mad, r) <- st ad <- unsafeFreezeArrayData mad return (ad, r)+ +-- Array tuple operations+-- ----------------------++fstArrayData :: ArrayData (a, b) -> ArrayData a+fstArrayData (AD_Pair x _) = x++sndArrayData :: ArrayData (a, b) -> ArrayData b+sndArrayData (AD_Pair _ y) = y++pairArrayData :: ArrayData a -> ArrayData b -> ArrayData (a, b)+pairArrayData = AD_Pair++++-- Auxilliary functions+-- --------------------++-- Our own version of the 'STUArray' allocation that uses /pinned/ memory,+-- which is aligned to 16 bytes.+--+unsafeNewArray_ :: Int -> (Int# -> Int#) -> ST s (STUArray s Int e)+unsafeNewArray_ n@(I# n#) elemsToBytes+ = ST $ \s1# ->+ case newPinnedByteArray# (elemsToBytes n#) s1# of+ (# s2#, marr# #) ->+ (# s2#, STUArray 0 (n - 1) n marr# #)++-- Obtains a pointer to the payload of an unboxed array.+--+-- PRECONDITION: The unboxed array must be pinned.+--+uArrayPtr :: UArray Int a -> Ptr a+uArrayPtr (UArray _ _ _ ba) = Ptr (byteArrayContents# ba)++-- Obtains a pointer to the payload of an unboxed ST array.+--+-- PRECONDITION: The unboxed ST array must be pinned.+--+sTUArrayPtr :: STUArray s Int a -> ST s (Ptr a)+sTUArrayPtr (STUArray _ _ _ mba) = ST $ \s ->+ case unsafeFreezeByteArray# mba s of+ (# s, ba #) -> (# s, Ptr (byteArrayContents# ba) #)
Data/Array/Accelerate/Array/Representation.hs view
@@ -16,9 +16,6 @@ ) where --- friends-import Data.Array.Accelerate.Type- -- |Index representation -- -
Data/Array/Accelerate/Array/Sugar.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE GADTs, TypeFamilies, FlexibleContexts, FlexibleInstances #-}-{-# LANGUAGE ScopedTypeVariables, DeriveDataTypeable #-}+{-# LANGUAGE CPP, ScopedTypeVariables, DeriveDataTypeable #-} {-# LANGUAGE UndecidableInstances #-} -- for instance SliceIxConv sl -- |Embedded array processing language: user-visible array operations@@ -29,14 +29,16 @@ ShapeBase, Shape, Ix(..), All(..), SliceIx(..), convertSliceIndex, -- * Array shape query, indexing, and conversions- shape, (!), newArray, fromIArray, toIArray, fromList, toList+ shape, (!), newArray, fromIArray, toIArray, fromList, toList,+ + -- * Array analysis+ arrayType ) where -- standard library import Data.Array.IArray (IArray) import qualified Data.Array.IArray as IArray-import qualified Data.Ix as IArray import Data.Typeable import Unsafe.Coerce @@ -45,7 +47,11 @@ import Data.Array.Accelerate.Array.Data import qualified Data.Array.Accelerate.Array.Representation as Repr +#ifdef ACCELERATE_CUDA_BACKEND+import qualified Data.Array.Accelerate.CUDA.Array.Data as CUDA+#endif + -- |Representation change for array element types -- ---------------------------------------------- @@ -138,122 +144,125 @@ -- |Class that characterises the types of values that can be array elements. -- class (Show a, Typeable a, - Typeable (ElemRepr a), Typeable (ElemRepr' a),- ArrayElem (ElemRepr a), ArrayElem (ElemRepr' a)) +#ifdef ACCELERATE_CUDA_BACKEND+ CUDA.ArrayElem (ElemRepr a), CUDA.ArrayElem (ElemRepr' a),+#endif+ Typeable (ElemRepr a), Typeable (ElemRepr' a),+ ArrayElem (ElemRepr a), ArrayElem (ElemRepr' a)) => Elem a where- --elemType :: {-dummy-} a -> TupleType (ElemRepr a)+ elemType :: {-dummy-} a -> TupleType (ElemRepr a) fromElem :: a -> ElemRepr a toElem :: ElemRepr a -> a - --elemType' :: {-dummy-} a -> TupleType (ElemRepr' a)+ elemType' :: {-dummy-} a -> TupleType (ElemRepr' a) fromElem' :: a -> ElemRepr' a toElem' :: ElemRepr' a -> a instance Elem () where- --elemType _ = UnitTuple+ elemType _ = UnitTuple fromElem = id toElem = id - --elemType' _ = UnitTuple+ elemType' _ = UnitTuple fromElem' = id toElem' = id instance Elem All where- --elemType _ = PairTuple UnitTuple UnitTuple+ elemType _ = PairTuple UnitTuple UnitTuple fromElem All = ((), ()) toElem ((), ()) = All - --elemType' _ = UnitTuple+ elemType' _ = UnitTuple fromElem' All = () toElem' () = All instance Elem Int where- --elemType = singletonScalarType+ elemType = singletonScalarType fromElem v = ((), v) toElem ((), v) = v - --elemType' _ = SingleTuple scalarType+ elemType' _ = SingleTuple scalarType fromElem' = id toElem' = id instance Elem Int8 where- --elemType = singletonScalarType+ elemType = singletonScalarType fromElem v = ((), v) toElem ((), v) = v - --elemType' _ = SingleTuple scalarType+ elemType' _ = SingleTuple scalarType fromElem' = id toElem' = id instance Elem Int16 where- --elemType = singletonScalarType+ elemType = singletonScalarType fromElem v = ((), v) toElem ((), v) = v - --elemType' _ = SingleTuple scalarType+ elemType' _ = SingleTuple scalarType fromElem' = id toElem' = id instance Elem Int32 where- --elemType = singletonScalarType+ elemType = singletonScalarType fromElem v = ((), v) toElem ((), v) = v - --elemType' _ = SingleTuple scalarType+ elemType' _ = SingleTuple scalarType fromElem' = id toElem' = id instance Elem Int64 where- --elemType = singletonScalarType+ elemType = singletonScalarType fromElem v = ((), v) toElem ((), v) = v - --elemType' _ = SingleTuple scalarType+ elemType' _ = SingleTuple scalarType fromElem' = id toElem' = id instance Elem Word where- --elemType = singletonScalarType+ elemType = singletonScalarType fromElem v = ((), v) toElem ((), v) = v - --elemType' _ = SingleTuple scalarType+ elemType' _ = SingleTuple scalarType fromElem' = id toElem' = id instance Elem Word8 where- --elemType = singletonScalarType+ elemType = singletonScalarType fromElem v = ((), v) toElem ((), v) = v - --elemType' _ = SingleTuple scalarType+ elemType' _ = SingleTuple scalarType fromElem' = id toElem' = id instance Elem Word16 where- --elemType = singletonScalarType+ elemType = singletonScalarType fromElem v = ((), v) toElem ((), v) = v - --elemType' _ = SingleTuple scalarType+ elemType' _ = SingleTuple scalarType fromElem' = id toElem' = id instance Elem Word32 where- --elemType = singletonScalarType+ elemType = singletonScalarType fromElem v = ((), v) toElem ((), v) = v - --elemType' _ = SingleTuple scalarType+ elemType' _ = SingleTuple scalarType fromElem' = id toElem' = id instance Elem Word64 where- --elemType = singletonScalarType+ elemType = singletonScalarType fromElem v = ((), v) toElem ((), v) = v - --elemType' _ = SingleTuple scalarType+ elemType' _ = SingleTuple scalarType fromElem' = id toElem' = id @@ -332,20 +341,20 @@ -} instance Elem Float where- --elemType = singletonScalarType+ elemType = singletonScalarType fromElem v = ((), v) toElem ((), v) = v - --elemType' _ = SingleTuple scalarType+ elemType' _ = SingleTuple scalarType fromElem' = id toElem' = id instance Elem Double where- --elemType = singletonScalarType+ elemType = singletonScalarType fromElem v = ((), v) toElem ((), v) = v - --elemType' _ = SingleTuple scalarType+ elemType' _ = SingleTuple scalarType fromElem' = id toElem' = id @@ -370,20 +379,20 @@ -} instance Elem Bool where- --elemType = singletonScalarType+ elemType = singletonScalarType fromElem v = ((), v) toElem ((), v) = v - --elemType' _ = SingleTuple scalarType+ elemType' _ = SingleTuple scalarType fromElem' = id toElem' = id instance Elem Char where- --elemType = singletonScalarType+ elemType = singletonScalarType fromElem v = ((), v) toElem ((), v) = v - --elemType' _ = SingleTuple scalarType+ elemType' _ = SingleTuple scalarType fromElem' = id toElem' = id @@ -417,74 +426,56 @@ -} instance (Elem a, Elem b) => Elem (a, b) where-{- elemType (_::(a, b)) = PairTuple (elemType (undefined :: a)) (elemType' (undefined :: b))--} fromElem (a, b) = (fromElem a, fromElem' b) toElem (a, b) = (toElem a, toElem' b) -{- elemType' (_::(a, b)) = PairTuple (elemType (undefined :: a)) (elemType' (undefined :: b))--} fromElem' (a, b) = (fromElem a, fromElem' b) toElem' (a, b) = (toElem a, toElem' b) instance (Elem a, Elem b, Elem c) => Elem (a, b, c) where-{- elemType (_::(a, b, c)) = PairTuple (elemType (undefined :: (a, b))) (elemType' (undefined :: c))--} fromElem (a, b, c) = (fromElem (a, b), fromElem' c) toElem (ab, c) = let (a, b) = toElem ab in (a, b, toElem' c) -{- elemType' (_::(a, b, c)) = PairTuple (elemType (undefined :: (a, b))) (elemType' (undefined :: c))--} fromElem' (a, b, c) = (fromElem (a, b), fromElem' c) toElem' (ab, c) = let (a, b) = toElem ab in (a, b, toElem' c) instance (Elem a, Elem b, Elem c, Elem d) => Elem (a, b, c, d) where-{- elemType (_::(a, b, c, d)) = PairTuple (elemType (undefined :: (a, b, c))) (elemType' (undefined :: d))--} fromElem (a, b, c, d) = (fromElem (a, b, c), fromElem' d) toElem (abc, d) = let (a, b, c) = toElem abc in (a, b, c, toElem' d) -{- elemType' (_::(a, b, c, d)) = PairTuple (elemType (undefined :: (a, b, c))) (elemType' (undefined :: d))--} fromElem' (a, b, c, d) = (fromElem (a, b, c), fromElem' d) toElem' (abc, d) = let (a, b, c) = toElem abc in (a, b, c, toElem' d) instance (Elem a, Elem b, Elem c, Elem d, Elem e) => Elem (a, b, c, d, e) where-{- elemType (_::(a, b, c, d, e)) = PairTuple (elemType (undefined :: (a, b, c, d))) (elemType' (undefined :: e))--} fromElem (a, b, c, d, e) = (fromElem (a, b, c, d), fromElem' e) toElem (abcd, e) = let (a, b, c, d) = toElem abcd in (a, b, c, d, toElem' e) -{- elemType' (_::(a, b, c, d, e)) = PairTuple (elemType (undefined :: (a, b, c, d))) (elemType' (undefined :: e))--} fromElem' (a, b, c, d, e) = (fromElem (a, b, c, d), fromElem' e) toElem' (abcd, e) = let (a, b, c, d) = toElem abcd in (a, b, c, d, toElem' e) -{-} -- |Convenience functions -- - singletonScalarType :: IsScalar a => a -> TupleType ((), a) singletonScalarType _ = PairTuple UnitTuple (SingleTuple scalarType)--} liftToElem :: (Elem a, Elem b) => (ElemRepr a -> ElemRepr b)@@ -713,7 +704,7 @@ = adata `seq` Array (fromElem sh) adata where (adata, _) = runArrayData $ do- arr <- newArrayData (size sh)+ arr <- newArrayData (1024 `max` size sh) let write ix = writeArrayData arr (index sh ix) (fromElem (f ix)) iter sh write (>>) (return ())@@ -756,3 +747,12 @@ instance Show (Array dim e) where show arr@(Array sh _adata) = "Array " ++ show (toElem sh :: dim) ++ " " ++ show (toList arr)+++-- Array analysis+-- --------------++-- |Reify the element type of an array.+--+arrayType :: forall dim e. Array dim e -> TupleType (ElemRepr e)+arrayType (Array _ _) = elemType (undefined::e)
+ Data/Array/Accelerate/CUDA.hs view
@@ -0,0 +1,39 @@+-- |+-- Module : Data.Array.Accelerate.CUDA+-- Copyright : [2008..2010] Manuel M T Chakravarty, Gabriele Keller, Sean Lee, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Manuel M T Chakravarty <chak@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--+-- This module is the CUDA backend for the embedded array language.+--++module Data.Array.Accelerate.CUDA (++ -- * Generate and execute CUDA code for an array expression+ Arrays, run++ ) where++import Data.Array.Accelerate.AST+import Data.Array.Accelerate.CUDA.State+import Data.Array.Accelerate.CUDA.Compile+import Data.Array.Accelerate.CUDA.Execute+import Data.Array.Accelerate.CUDA.Array.Device+import qualified Data.Array.Accelerate.Smart as Sugar+++-- Accelerate: CUDA+-- ~~~~~~~~~~~~~~~~++-- | Compiles and run a complete embedded array program using the CUDA backend+--+run :: Arrays a => Sugar.Acc a -> IO a+run acc = evalCUDA+ $ execute (Sugar.convertAcc acc) >>= collect++execute :: Arrays a => Acc a -> CIO a+execute acc = compileAcc acc >> executeAcc acc+
+ Data/Array/Accelerate/CUDA/Analysis/Hash.hs view
@@ -0,0 +1,71 @@+{-# LANGUAGE GADTs #-}+-- |+-- Module : Data.Array.Accelerate.CUDA.Analysis.Hash+-- Copyright : [2008..2010] Manuel M T Chakravarty, Gabriele Keller, Sean Lee, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Manuel M T Chakravarty <chak@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-partable (GHC extensions)+--++module Data.Array.Accelerate.CUDA.Analysis.Hash (accToKey)+ where++import Data.Char+import Data.Array.Accelerate.AST+import Data.Array.Accelerate.Type+import Data.Array.Accelerate.Pretty ()+import Data.Array.Accelerate.Analysis.Type+import Data.Array.Accelerate.CUDA.State+++-- |+-- Generate a unique key for each kernel computation (not extensively tested...)+--+accToKey :: OpenAcc aenv a -> Key+accToKey (Unit e) = chr 2 : showTy (expType e) ++ show e+accToKey (Reshape _ a) = chr 7 : showTy (accType a)+accToKey (Replicate _ e a) = chr 17 : showTy (accType a) ++ show e+accToKey (Index _ a e) = chr 29 : showTy (accType a) ++ show e+accToKey (Map f a) = chr 41 : showTy (accType a) ++ show f+accToKey (ZipWith f x y) = chr 53 : showTy (accType x) ++ showTy (accType y) ++ show f+accToKey (Fold f e a) = chr 67 : showTy (accType a) ++ show f ++ show e+accToKey (FoldSeg f e _ a) = chr 79 : showTy (accType a) ++ show f ++ show e+accToKey (Scanl f e a) = chr 97 : showTy (accType a) ++ show f ++ show e+accToKey (Scanr f e a) = chr 107 : showTy (accType a) ++ show f ++ show e+accToKey (Permute c e p a) = chr 127 : showTy (accType a) ++ show c ++ show e ++ show p+accToKey (Backpermute p _ a) = chr 139 : showTy (accType a) ++ show p+accToKey _ =+ error "we should never get here"++showTy :: TupleType a -> String+showTy UnitTuple = []+showTy (SingleTuple ty) = show ty+showTy (PairTuple a b) = showTy a ++ showTy b++{-+-- hash function from the dragon book pp437; assumes 7 bit characters and needs+-- the (nearly) full range of values guaranteed for `Int' by the Haskell+-- language definition; can handle 8 bit characters provided we have 29 bit for+-- the `Int's without sign+--+quad :: String -> Int+quad (c1:c2:c3:c4:s) = (( ord c4 * bits21+ + ord c3 * bits14+ + ord c2 * bits7+ + ord c1)+ `Prelude.mod` bits28)+ + (quad s `Prelude.mod` bits28)+quad (c1:c2:c3:[] ) = ord c3 * bits14 + ord c2 * bits7 + ord c1+quad (c1:c2:[] ) = ord c2 * bits7 + ord c1+quad (c1:[] ) = ord c1+quad ([] ) = 0++bits7, bits14, bits21, bits28 :: Int+bits7 = 2^(7 ::Int)+bits14 = 2^(14::Int)+bits21 = 2^(21::Int)+bits28 = 2^(28::Int)+-}+
+ Data/Array/Accelerate/CUDA/Analysis/Launch.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE GADTs #-}+-- |+-- Module : Data.Array.Accelerate.CUDA.Analysis.Launch+-- Copyright : [2008..2010] Manuel M T Chakravarty, Gabriele Keller, Sean Lee, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Manuel M T Chakravarty <chak@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-partable (GHC extensions)+--++module Data.Array.Accelerate.CUDA.Analysis.Launch (launchConfig)+ where++import Control.Monad.IO.Class++import Data.Array.Accelerate.AST+import Data.Array.Accelerate.Analysis.Type++import Data.Array.Accelerate.CUDA.State+import qualified Foreign.CUDA.Analysis as CUDA+import qualified Foreign.CUDA.Driver as CUDA+++-- |+-- Determine kernel launch parameters for the given array computation (as well+-- as compiled function module). This consists of the thread block size, number+-- of blocks, and dynamically allocated shared memory (bytes), respectively.+--+-- By default, this launches the kernel with the minimum block size that gives+-- maximum occupancy, and the grid size limited to the maximum number of+-- physically resident blocks. Hence, kernels may need to process multiple+-- elements per thread.+--+-- TLM: this could probably be stored in the KernelEntry+--+launchConfig :: OpenAcc aenv a -> Int -> CUDA.Fun -> CIO (Int, Int, Integer)+launchConfig acc n fn = do+ regs <- liftIO $ CUDA.requires fn CUDA.NumRegs+ stat <- liftIO $ CUDA.requires fn CUDA.SharedSizeBytes -- static memory only+ prop <- getM deviceProps++ let dyn = sharedMem acc+ (cta, occ) = CUDA.optimalBlockSize prop (const regs) ((stat+) . dyn)+ mbk = CUDA.multiProcessorCount prop * CUDA.activeThreadBlocks occ++ return (cta, mbk `min` gridSize acc n cta, toInteger (dyn cta))+++-- |+-- Determine the number of blocks of the given size necessary to process the+-- given array expression. This should understand things like #elements per+-- thread for the various kernels.+--+gridSize :: OpenAcc aenv a -> Int -> Int -> Int+gridSize acc size cta =+ let between arr n = (n+arr-1) `div` n+ in 1 `max` ((cta - 1 + (size `between` elementsPerThread acc)) `div` cta)++elementsPerThread :: OpenAcc aenv a -> Int+elementsPerThread _ = 1+++-- |+-- Analyse the given array expression, returning an estimate of dynamic shared+-- memory usage as a function of thread block size. This can be used by the+-- occupancy calculator to optimise kernel launch shape.+--+sharedMem :: OpenAcc aenv a -> Int -> Int+sharedMem (Fold _ x _) t = sizeOf (expType x) * t+sharedMem (Scanl _ x _) t = sizeOf (expType x) * t+sharedMem (Scanr _ x _) t = sizeOf (expType x) * t+sharedMem _ _ = 0+
+ Data/Array/Accelerate/CUDA/Array/Data.hs view
@@ -0,0 +1,345 @@+{-# LANGUAGE CPP, FlexibleContexts, TypeFamilies #-}+{-# LANGUAGE ExistentialQuantification, ScopedTypeVariables #-}+-- |+-- Module : Data.Array.Accelerate.CUDA.Array.Data+-- Copyright : [2008..2010] Manuel M T Chakravarty, Gabriele Keller, Sean Lee, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Manuel M T Chakravarty <chak@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--++module Data.Array.Accelerate.CUDA.Array.Data+ (+ ArrayElem(..)+ ) where++import Prelude hiding (id, (.), mod)+import Control.Category++import Foreign.Ptr+import Foreign.Storable (Storable, sizeOf)+import qualified Foreign as F++import Data.Int+import Data.Word+import Data.Maybe+import Control.Monad+import Control.Applicative+import Control.Monad.IO.Class+import qualified Data.IntMap as IM++import Data.Array.Accelerate.CUDA.State+import qualified Data.Array.Accelerate.Array.Data as Acc+import qualified Foreign.CUDA.Driver as CUDA+import qualified Foreign.CUDA.Driver.Stream as CUDA+import qualified Foreign.CUDA.Driver.Texture as CUDA+++-- Instances+-- ~~~~~~~~~++class Acc.ArrayElem e => ArrayElem e where+ type DevicePtrs e+ type HostPtrs e+ mallocArray :: Acc.ArrayData e -> Int -> CIO ()+ indexArray :: Acc.ArrayData e -> Int -> CIO e+ copyArray :: Acc.ArrayData e -> Acc.ArrayData e -> Int -> CIO ()+ peekArray :: Acc.ArrayData e -> Int -> CIO ()+ pokeArray :: Acc.ArrayData e -> Int -> CIO ()+ peekArrayAsync :: Acc.ArrayData e -> Int -> Maybe CUDA.Stream -> CIO ()+ pokeArrayAsync :: Acc.ArrayData e -> Int -> Maybe CUDA.Stream -> CIO ()+ textureRefs :: Acc.ArrayData e -> CUDA.Module -> Int -> Int -> CIO [CUDA.FunParam]+ devicePtrs :: Acc.ArrayData e -> CIO [CUDA.FunParam]+ touchArray :: Acc.ArrayData e -> CIO ()+ freeArray :: Acc.ArrayData e -> CIO ()++ -- FIXME: remove once all ArrayElem instances are concrete+ mallocArray = undefined+ indexArray = undefined+ copyArray = undefined+ peekArray = undefined+ pokeArray = undefined+ peekArrayAsync = undefined+ pokeArrayAsync = undefined+ textureRefs = undefined+ devicePtrs = undefined+ touchArray = undefined+ freeArray = undefined+++instance ArrayElem () where+ type DevicePtrs () = CUDA.DevicePtr ()+ type HostPtrs () = CUDA.HostPtr ()+ mallocArray _ _ = return ()+ indexArray _ _ = return ()+ copyArray _ _ _ = return ()+ peekArray _ _ = return ()+ pokeArray _ _ = return ()+ peekArrayAsync _ _ _ = return ()+ pokeArrayAsync _ _ _ = return ()+ textureRefs _ _ _ _ = return []+ devicePtrs _ = return []+ touchArray _ = return ()+ freeArray _ = return ()+++#define primArrayElem_(ty,con) \+instance ArrayElem ty where { \+ type DevicePtrs ty = CUDA.DevicePtr con \+; type HostPtrs ty = CUDA.HostPtr con \+; mallocArray = mallocArray' \+; indexArray = indexArray' \+; copyArray = copyArray' \+; peekArray = peekArray' \+; pokeArray = pokeArray' \+; peekArrayAsync = peekArrayAsync' \+; pokeArrayAsync = pokeArrayAsync' \+; textureRefs = textureRefs' \+; devicePtrs = devicePtrs' \+; touchArray = touchArray' \+; freeArray = freeArray' }++#define primArrayElem(ty) primArrayElem_(ty,ty)++primArrayElem(Int)+primArrayElem(Int8)+primArrayElem(Int16)+primArrayElem(Int32)+primArrayElem(Int64)++primArrayElem(Word)+primArrayElem(Word8)+primArrayElem(Word16)+primArrayElem(Word32)+primArrayElem(Word64)++-- FIXME:+-- CShort+-- CUShort+-- CInt+-- CUInt+-- CLong+-- CULong+-- CLLong+-- CULLong++primArrayElem(Float)+primArrayElem(Double)++-- FIXME:+-- CFloat+-- CDouble++-- FIXME:+-- No concrete implementation in Data.Array.Accelerate.Array.Data+--+instance ArrayElem Bool+instance ArrayElem Char++-- FIXME:+-- CChar+-- CSChar+-- CUChar++instance (ArrayElem a, ArrayElem b) => ArrayElem (a,b) where+ type DevicePtrs (a,b) = (DevicePtrs a, DevicePtrs b)+ type HostPtrs (a,b) = (HostPtrs a, HostPtrs b)++ mallocArray ad n = mallocArray (fst' ad) n *> mallocArray (snd' ad) n+ peekArray ad n = peekArray (fst' ad) n *> peekArray (snd' ad) n+ pokeArray ad n = pokeArray (fst' ad) n *> pokeArray (snd' ad) n+ copyArray src dst n = copyArray (fst' src) (fst' dst) n *> copyArray (snd' src) (snd' dst) n+ peekArrayAsync ad n s = peekArrayAsync (fst' ad) n s *> peekArrayAsync (snd' ad) n s+ pokeArrayAsync ad n s = pokeArrayAsync (fst' ad) n s *> pokeArrayAsync (snd' ad) n s+ touchArray ad = touchArray (fst' ad) *> touchArray (snd' ad)+ freeArray ad = freeArray (fst' ad) *> freeArray (snd' ad)+ indexArray ad n = (,) <$> indexArray (fst' ad) n <*> indexArray (snd' ad) n+ devicePtrs ad = (++) <$> devicePtrs (fst' ad) <*> devicePtrs (snd' ad)+ textureRefs ad mdl n t = do -- PRETTY ME+ t1 <- textureRefs (fst' ad) mdl n t+ t2 <- textureRefs (snd' ad) mdl n (t+ length t1)+ return (t1 ++ t2)+++-- Texture References+-- ~~~~~~~~~~~~~~~~~~++-- This representation must match the code generator's understanding of how to+-- utilise the texture cache.+--+-- FIXME: Code generation for 64-bit types.+--+class TextureData a where+ format :: a -> (CUDA.Format, Int)++instance TextureData Int8 where format _ = (CUDA.Int8, 1)+instance TextureData Int16 where format _ = (CUDA.Int16, 1)+instance TextureData Int32 where format _ = (CUDA.Int32, 1)+instance TextureData Int64 where format _ = (CUDA.Int32, 2)+instance TextureData Word8 where format _ = (CUDA.Word8, 1)+instance TextureData Word16 where format _ = (CUDA.Word16, 1)+instance TextureData Word32 where format _ = (CUDA.Word32, 1)+instance TextureData Word64 where format _ = (CUDA.Word32, 2)+instance TextureData Float where format _ = (CUDA.Float, 1)+instance TextureData Double where format _ = (CUDA.Int32, 2)++instance TextureData Int where+ format _ = case sizeOf (undefined :: Int) of+ 4 -> (CUDA.Int32, 1)+ 8 -> (CUDA.Int32, 2)+ _ -> error "we can never get here"++instance TextureData Word where+ format _ = case sizeOf (undefined :: Word) of+ 4 -> (CUDA.Word32, 1)+ 8 -> (CUDA.Word32, 2)+ _ -> error "we can never get here"+++-- Implementation+-- ~~~~~~~~~~~~~~++-- Allocate a new device array to accompany the given host-side Accelerate array+--+mallocArray' :: (Acc.ArrayPtrs e ~ Ptr a, Storable a, Acc.ArrayElem e) => Acc.ArrayData e -> Int -> CIO ()+mallocArray' ad n = do+ exists <- IM.member key <$> getM memoryEntry+ unless exists $ insertArray ad =<< liftIO (CUDA.mallocArray n)+ where+ insertArray :: (Acc.ArrayPtrs e ~ Ptr a, Acc.ArrayElem e) => Acc.ArrayData e -> CUDA.DevicePtr a -> CIO ()+ insertArray _ = modM memoryEntry . IM.insert key . MemoryEntry 0 . CUDA.devPtrToWordPtr+ key = arrayToKey ad+++-- Array indexing+--+indexArray' :: (Acc.ArrayPtrs e ~ Ptr a, Storable a, Acc.ArrayElem e) => Acc.ArrayData e -> Int -> CIO a+indexArray' ad n = do+ dp <- getArray ad+ liftIO . F.alloca $ \p -> do+ CUDA.peekArray 1 (dp `CUDA.advanceDevPtr` n) p+ F.peek p+++-- Copy data between two device arrays+--+copyArray' :: forall a e. (Acc.ArrayPtrs e ~ Ptr a, Storable a, Acc.ArrayElem e) => Acc.ArrayData e -> Acc.ArrayData e -> Int -> CIO ()+copyArray' src' dst' n =+ let bytes = n * sizeOf (undefined::a)+ in do+ src <- getArray src'+ dst <- getArray dst'+ liftIO $ CUDA.copyArrayAsync bytes src dst+++-- Copy data from the device into the associated Accelerate array+--+peekArray' :: (Acc.ArrayPtrs e ~ Ptr a, Storable a, Acc.ArrayElem e) => Acc.ArrayData e -> Int -> CIO ()+peekArray' ad n =+ let dst = Acc.ptrsOfArrayData ad+ src = CUDA.wordPtrToDevPtr . get arena+ in+ lookupArray ad >>= \me -> liftIO $ CUDA.peekArray n (src me) dst++peekArrayAsync' :: (Acc.ArrayPtrs e ~ Ptr a, Storable a, Acc.ArrayElem e) => Acc.ArrayData e -> Int -> Maybe CUDA.Stream -> CIO ()+peekArrayAsync' ad n st =+ let dst = CUDA.HostPtr . Acc.ptrsOfArrayData+ src = CUDA.wordPtrToDevPtr . get arena+ in+ lookupArray ad >>= \me -> liftIO $ CUDA.peekArrayAsync n (src me) (dst ad) st+++-- Copy data from an Accelerate array to the associated device array. The data+-- will only be copied once, with subsequent invocations incrementing the+-- reference counter.+--+pokeArray' :: (Acc.ArrayPtrs e ~ Ptr a, Storable a, Acc.ArrayElem e) => Acc.ArrayData e -> Int -> CIO ()+pokeArray' ad n =+ let src = Acc.ptrsOfArrayData ad+ dst = CUDA.wordPtrToDevPtr . get arena+ in do+ me <- mod refcount (+1) <$> lookupArray ad+ when (get refcount me <= 1) . liftIO $ CUDA.pokeArray n src (dst me)+ modM memoryEntry (IM.insert (arrayToKey ad) me)++pokeArrayAsync' :: (Acc.ArrayPtrs e ~ Ptr a, Storable a, Acc.ArrayElem e) => Acc.ArrayData e -> Int -> Maybe CUDA.Stream -> CIO ()+pokeArrayAsync' ad n st =+ let src = CUDA.HostPtr . Acc.ptrsOfArrayData+ dst = CUDA.wordPtrToDevPtr . get arena+ in do+ me <- mod refcount (+1) <$> lookupArray ad+ when (get refcount me <= 1) . liftIO $ CUDA.pokeArrayAsync n (src ad) (dst me) st+ modM memoryEntry (IM.insert (arrayToKey ad) me)+++-- Release a device array, when its reference counter drops to zero+--+freeArray' :: (Acc.ArrayPtrs e ~ Ptr a, Acc.ArrayElem e) => Acc.ArrayData e -> CIO ()+freeArray' ad = do+ me <- mod refcount (subtract 1) <$> lookupArray ad+ if get refcount me > 0+ then modM memoryEntry (IM.insert (arrayToKey ad) me)+ else do liftIO . CUDA.free . CUDA.wordPtrToDevPtr $ get arena me+ modM memoryEntry (IM.delete (arrayToKey ad))+++-- Increase the reference count of an array. You may wish to call this right+-- before another method that will implicitly attempt to release the array.+--+touchArray' :: (Acc.ArrayPtrs e ~ Ptr a, Acc.ArrayElem e) => Acc.ArrayData e -> CIO ()+touchArray' ad = modM memoryEntry =<< IM.insert (arrayToKey ad) . mod refcount (+1) <$> lookupArray ad+++-- Return the device pointers wrapped in a list of function parameters+--+devicePtrs' :: (Acc.ArrayPtrs e ~ Ptr a, Acc.ArrayElem e) => Acc.ArrayData e -> CIO [CUDA.FunParam]+devicePtrs' ad = (: []) . CUDA.VArg . CUDA.wordPtrToDevPtr . get arena <$> lookupArray ad+++-- Retrieve texture references from the module (beginning with the given seed),+-- bind device pointers, and return as a list of function arguments.+--+textureRefs' :: forall a e. (Acc.ArrayPtrs e ~ Ptr a, Acc.ArrayElem e, Storable a, TextureData a)+ => Acc.ArrayData e -> CUDA.Module -> Int -> Int -> CIO [CUDA.FunParam]+textureRefs' ad mdl n t = do+ ptr <- getArray ad+ tex <- liftIO $ CUDA.getTex mdl ("tex" ++ show t)+ liftIO $ uncurry (CUDA.setFormat tex) (format (undefined :: a))+ liftIO $ CUDA.bind tex ptr (fromIntegral $ n * sizeOf (undefined :: a))+ return [CUDA.TArg tex]+++-- Utilities+-- ~~~~~~~~~++-- Generate a memory map key from the given ArrayData+--+arrayToKey :: (Acc.ArrayPtrs e ~ Ptr a, Acc.ArrayElem e) => Acc.ArrayData e -> IM.Key+arrayToKey = fromIntegral . ptrToWordPtr . Acc.ptrsOfArrayData+{-# INLINE arrayToKey #-}++-- Retrieve the device memory entry from the state structure associated with a+-- particular Accelerate array.+--+lookupArray :: (Acc.ArrayPtrs e ~ Ptr a, Acc.ArrayElem e) => Acc.ArrayData e -> CIO MemoryEntry+lookupArray ad = fromMaybe (error "ArrayElem: internal error") . IM.lookup (arrayToKey ad) <$> getM memoryEntry+{-# INLINE lookupArray #-}++-- Return the device pointer associated with a host-side Accelerate array+--+getArray :: (Acc.ArrayPtrs e ~ Ptr a, Acc.ArrayElem e) => Acc.ArrayData e -> CIO (CUDA.DevicePtr a)+getArray ad = CUDA.wordPtrToDevPtr . get arena <$> lookupArray ad+{-# INLINE getArray #-}++-- Array tuple extraction+--+fst' :: Acc.ArrayData (a,b) -> Acc.ArrayData a+fst' = Acc.fstArrayData+{-# INLINE fst' #-}++snd' :: Acc.ArrayData (a,b) -> Acc.ArrayData b+snd' = Acc.sndArrayData+{-# INLINE snd' #-}+
+ Data/Array/Accelerate/CUDA/Array/Device.hs view
@@ -0,0 +1,42 @@+{-# LANGUAGE TypeFamilies #-}+-- |+-- Module : Data.Array.Accelerate.CUDA+-- Copyright : [2008..2010] Manuel M T Chakravarty, Gabriele Keller, Sean Lee, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Manuel M T Chakravarty <chak@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--+--- Description ---------------------------------------------------------------+--+-- Embedded array processing language: device arrays+--++module Data.Array.Accelerate.CUDA.Array.Device+ where++import Control.Applicative++import Data.Array.Accelerate.CUDA.State+import Data.Array.Accelerate.CUDA.Array.Data+import Data.Array.Accelerate.Array.Representation+import Data.Array.Accelerate.Array.Sugar (Array(..))+++-- |+-- Characterises the types that may be retrieved from the CUDA device as the+-- result of executing an array program+--+class Arrays as where+ collect :: as -> CIO as -- ^ Copy from device to host, and decrement the usage counter++instance Arrays () where+ collect () = return ()++instance Arrays (Array dim e) where+ collect arr@(Array sh ad) = peekArray ad (size sh) >> freeArray ad >> return arr++instance (Arrays as1, Arrays as2) => Arrays (as1, as2) where+ collect (a1,a2) = (,) <$> collect a1 <*> collect a2+
+ Data/Array/Accelerate/CUDA/CodeGen.hs view
@@ -0,0 +1,475 @@+{-# LANGUAGE GADTs, PatternGuards, ExistentialQuantification, ScopedTypeVariables #-}+-- |+-- Module : Data.Array.Accelerate.CUDA.CodeGen+-- Copyright : [2008..2010] Manuel M T Chakravarty, Gabriele Keller, Sean Lee, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Manuel M T Chakravarty <chak@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--++module Data.Array.Accelerate.CUDA.CodeGen (codeGenAcc, CUTranslSkel)+ where++import Prelude hiding (mod)++import Data.Char+import Language.C+import Control.Applicative+import Control.Monad.State++import Data.Array.Accelerate.Type+import Data.Array.Accelerate.Tuple+import Data.Array.Accelerate.Pretty ()+import Data.Array.Accelerate.Analysis.Type+import qualified Data.Array.Accelerate.AST as AST+import qualified Data.Array.Accelerate.Array.Sugar as Sugar+import qualified Foreign.Storable as F++import Data.Array.Accelerate.CUDA.CodeGen.Data+import Data.Array.Accelerate.CUDA.CodeGen.Util+import Data.Array.Accelerate.CUDA.CodeGen.Skeleton+++-- Array expressions+-- ~~~~~~~~~~~~~~~~~++-- | Generate CUDA device code for an array expression+--+codeGenAcc :: AST.OpenAcc aenv a -> CUTranslSkel+codeGenAcc acc =+ let (CUTranslSkel code skel, fvar) = runState (codeGenAcc' acc) []+ CTranslUnit decl node = code+ in+ CUTranslSkel (CTranslUnit (fvar ++ decl) node) skel++-- FIXME:+-- The actual code generation workhorse. We run under a state which keeps track+-- of the free array variables encountered so far. This is used to determine+-- which reference to texture read from. Assumes the same traversal behaviour+-- during execution.+--+-- FRAGILE.+--+type CG a = State [CExtDecl] a++codeGenAcc' :: AST.OpenAcc aenv a -> CG CUTranslSkel+codeGenAcc' op@(AST.Map f1 a1) = mkMap (codeGenAccType op) (codeGenAccType a1) <$> codeGenFun f1+codeGenAcc' op@(AST.ZipWith f1 a1 a2) = mkZipWith (codeGenAccType op) (codeGenAccType a1) (codeGenAccType a2) <$> codeGenFun f1+codeGenAcc' (AST.Replicate _ e1 a1) = mkReplicate (codeGenAccType a1) <$> codeGenExp e1+codeGenAcc' (AST.Index _ a1 e1) = mkIndex (codeGenAccType a1) <$> codeGenExp e1+codeGenAcc' (AST.Fold f1 e1 _) = mkFold (codeGenExpType e1) <$> codeGenExp e1 <*> codeGenFun f1+codeGenAcc' (AST.FoldSeg f1 e1 _ _) = mkFoldSeg (codeGenExpType e1) <$> codeGenExp e1 <*> codeGenFun f1+codeGenAcc' (AST.Scanl f1 e1 _) = mkScanl (codeGenExpType e1) <$> codeGenExp e1 <*> codeGenFun f1+codeGenAcc' (AST.Scanr f1 e1 _) = mkScanr (codeGenExpType e1) <$> codeGenExp e1 <*> codeGenFun f1+codeGenAcc' (AST.Permute f1 _ f2 a1) = mkPermute (codeGenAccType a1) <$> codeGenFun f1 <*> codeGenFun f2+codeGenAcc' (AST.Backpermute _ f1 a1) = mkBackpermute (codeGenAccType a1) <$> codeGenFun f1++codeGenAcc' _ =+ error "codeGenAcc: internal error"+++-- Embedded expressions+-- ~~~~~~~~~~~~~~~~~~~~++-- Function abstraction+--+codeGenFun :: AST.OpenFun env aenv t -> CG [CExpr]+codeGenFun (AST.Lam lam) = codeGenFun lam+codeGenFun (AST.Body body) = codeGenExp body++unit :: a -> [a]+unit x = [x]++-- Implementation of 'IndexScalar' and 'Shape' demonstrate that array+-- computations must be hoisted out of scalar expressions before code generation+-- or execution: kernel functions can not invoke other array computations.+--+-- TLM 2010-06-24: Shape for free array variables??+--+codeGenExp :: forall env aenv t. AST.OpenExp env aenv t -> CG [CExpr]+codeGenExp (AST.Shape _) = return . unit $ CVar (internalIdent "shape") internalNode+codeGenExp (AST.PrimConst c) = return . unit $ codeGenPrimConst c+codeGenExp (AST.PrimApp f arg) = unit . codeGenPrim f <$> codeGenExp arg+codeGenExp (AST.Const c) = return $ codeGenConst (Sugar.elemType (undefined::t)) c+codeGenExp (AST.Var i) =+ let var = CVar (internalIdent ('x' : show (idxToInt i))) internalNode+ in case codeGenTupleType (Sugar.elemType (undefined::t)) of+ [_] -> return [var]+ cps -> return . reverse . take (length cps) . flip map ['a'..] $+ \c -> CMember var (internalIdent [c]) False internalNode++codeGenExp (AST.Cond p e1 e2) = do+ [a] <- codeGenExp p+ [b] <- codeGenExp e1+ [c] <- codeGenExp e2+ return [CCond a (Just b) c internalNode]++codeGenExp (AST.Tuple t) = codeGenTup t+codeGenExp (AST.Prj idx e) = do+ [var] <- codeGenExp e+ return [CMember var (internalIdent [enumFrom 'a' !! prjToInt idx]) False internalNode]++codeGenExp (AST.IndexScalar a1 e1) = do+ n <- length <$> get+ [i] <- codeGenExp e1+ let ty = codeGenTupleTex (accType a1)+ fv = map (\x -> "tex" ++ show x) [n..]++ modify (++ zipWith globalDecl ty fv)+ return (zipWith (indexArray i) fv ty)++ where+ globalDecl ty name = CDeclExt (CDecl (map CTypeSpec ty) [(Just (CDeclr (Just (internalIdent name)) [] Nothing [] internalNode),Nothing,Nothing)] internalNode)+ indexArray idx name [CDoubleType _] = CCall (CVar (internalIdent "indexDArray") internalNode) [CVar (internalIdent name) internalNode, idx] internalNode+ indexArray idx name _ = CCall (CVar (internalIdent "indexArray") internalNode) [CVar (internalIdent name) internalNode, idx] internalNode+++-- Tuples are defined as snoc-lists, so generate code right-to-left+--+codeGenTup :: Tuple (AST.OpenExp env aenv) t -> CG [CExpr]+codeGenTup NilTup = return []+codeGenTup (t `SnocTup` e) = (++) <$> codeGenTup t <*> codeGenExp e+++-- Convert a typed de Brujin index to the corresponding integer+--+idxToInt :: AST.Idx env t -> Int+idxToInt AST.ZeroIdx = 0+idxToInt (AST.SuccIdx idx) = 1 + idxToInt idx++-- Convert a tuple index into the corresponding integer+--+prjToInt :: TupleIdx t e -> Int+prjToInt ZeroTupIdx = 0+prjToInt (SuccTupIdx idx) = 1 + prjToInt idx+++-- Types+-- ~~~~~++-- Generate types for the reified elements of an array computation+--+codeGenAccType :: AST.OpenAcc aenv (Sugar.Array dim e) -> [CType]+codeGenAccType = codeGenTupleType . accType++codeGenExpType :: AST.OpenExp aenv env t -> [CType]+codeGenExpType = codeGenTupleType . expType+++-- Implementation+--+codeGenTupleType :: TupleType a -> [CType]+codeGenTupleType UnitTuple = []+codeGenTupleType (SingleTuple ty) = [codeGenScalarType ty]+codeGenTupleType (PairTuple t1 t0) = codeGenTupleType t1 ++ codeGenTupleType t0++codeGenScalarType :: ScalarType a -> CType+codeGenScalarType (NumScalarType ty) = codeGenNumType ty+codeGenScalarType (NonNumScalarType ty) = codeGenNonNumType ty++codeGenNumType :: NumType a -> CType+codeGenNumType (IntegralNumType ty) = codeGenIntegralType ty+codeGenNumType (FloatingNumType ty) = codeGenFloatingType ty++codeGenIntegralType :: IntegralType a -> CType+codeGenIntegralType (TypeInt8 _) = [CTypeDef (internalIdent "int8_t") internalNode]+codeGenIntegralType (TypeInt16 _) = [CTypeDef (internalIdent "int16_t") internalNode]+codeGenIntegralType (TypeInt32 _) = [CTypeDef (internalIdent "int32_t") internalNode]+codeGenIntegralType (TypeInt64 _) = [CTypeDef (internalIdent "int64_t") internalNode]+codeGenIntegralType (TypeWord8 _) = [CTypeDef (internalIdent "uint8_t") internalNode]+codeGenIntegralType (TypeWord16 _) = [CTypeDef (internalIdent "uint16_t") internalNode]+codeGenIntegralType (TypeWord32 _) = [CTypeDef (internalIdent "uint32_t") internalNode]+codeGenIntegralType (TypeWord64 _) = [CTypeDef (internalIdent "uint64_t") internalNode]+codeGenIntegralType (TypeCShort _) = [CShortType internalNode]+codeGenIntegralType (TypeCUShort _) = [CUnsigType internalNode, CShortType internalNode]+codeGenIntegralType (TypeCInt _) = [CIntType internalNode]+codeGenIntegralType (TypeCUInt _) = [CUnsigType internalNode, CIntType internalNode]+codeGenIntegralType (TypeCLong _) = [CLongType internalNode, CIntType internalNode]+codeGenIntegralType (TypeCULong _) = [CUnsigType internalNode, CLongType internalNode, CIntType internalNode]+codeGenIntegralType (TypeCLLong _) = [CLongType internalNode, CLongType internalNode, CIntType internalNode]+codeGenIntegralType (TypeCULLong _) = [CUnsigType internalNode, CLongType internalNode, CLongType internalNode, CIntType internalNode]++codeGenIntegralType (TypeInt _) =+ case F.sizeOf (undefined::Int) of+ 4 -> [CTypeDef (internalIdent "int32_t") internalNode]+ 8 -> [CTypeDef (internalIdent "int64_t") internalNode]+ _ -> error "we can never get here"++codeGenIntegralType (TypeWord _) =+ case F.sizeOf (undefined::Int) of+ 4 -> [CTypeDef (internalIdent "uint32_t") internalNode]+ 8 -> [CTypeDef (internalIdent "uint64_t") internalNode]+ _ -> error "we can never get here"++codeGenFloatingType :: FloatingType a -> CType+codeGenFloatingType (TypeFloat _) = [CFloatType internalNode]+codeGenFloatingType (TypeDouble _) = [CDoubleType internalNode]+codeGenFloatingType (TypeCFloat _) = [CFloatType internalNode]+codeGenFloatingType (TypeCDouble _) = [CDoubleType internalNode]++codeGenNonNumType :: NonNumType a -> CType+codeGenNonNumType (TypeBool _) = [CUnsigType internalNode, CCharType internalNode]+codeGenNonNumType (TypeChar _) = [CCharType internalNode]+codeGenNonNumType (TypeCChar _) = [CCharType internalNode]+codeGenNonNumType (TypeCSChar _) = [CSignedType internalNode, CCharType internalNode]+codeGenNonNumType (TypeCUChar _) = [CUnsigType internalNode, CCharType internalNode]+++-- Texture types+--+codeGenTupleTex :: TupleType a -> [CType]+codeGenTupleTex UnitTuple = []+codeGenTupleTex (SingleTuple t) = [codeGenScalarTex t]+codeGenTupleTex (PairTuple t1 t0) = codeGenTupleTex t1 ++ codeGenTupleTex t0++codeGenScalarTex :: ScalarType a -> CType+codeGenScalarTex (NumScalarType ty) = codeGenNumTex ty+codeGenScalarTex (NonNumScalarType ty) = codeGenNonNumTex ty;++codeGenNumTex :: NumType a -> CType+codeGenNumTex (IntegralNumType ty) = codeGenIntegralTex ty+codeGenNumTex (FloatingNumType ty) = codeGenFloatingTex ty++codeGenIntegralTex :: IntegralType a -> CType+codeGenIntegralTex (TypeInt8 _) = [CTypeDef (internalIdent "TexInt8") internalNode]+codeGenIntegralTex (TypeInt16 _) = [CTypeDef (internalIdent "TexInt16") internalNode]+codeGenIntegralTex (TypeInt32 _) = [CTypeDef (internalIdent "TexInt32") internalNode]+codeGenIntegralTex (TypeInt64 _) = [CTypeDef (internalIdent "TexInt64") internalNode]+codeGenIntegralTex (TypeWord8 _) = [CTypeDef (internalIdent "TexWord8") internalNode]+codeGenIntegralTex (TypeWord16 _) = [CTypeDef (internalIdent "TexWord16") internalNode]+codeGenIntegralTex (TypeWord32 _) = [CTypeDef (internalIdent "TexWord32") internalNode]+codeGenIntegralTex (TypeWord64 _) = [CTypeDef (internalIdent "TexWord64") internalNode]+codeGenIntegralTex (TypeCShort _) = [CTypeDef (internalIdent "TexCShort") internalNode]+codeGenIntegralTex (TypeCUShort _) = [CTypeDef (internalIdent "TexCUShort") internalNode]+codeGenIntegralTex (TypeCInt _) = [CTypeDef (internalIdent "TexCInt") internalNode]+codeGenIntegralTex (TypeCUInt _) = [CTypeDef (internalIdent "TexCUInt") internalNode]+codeGenIntegralTex (TypeCLong _) = [CTypeDef (internalIdent "TexCLong") internalNode]+codeGenIntegralTex (TypeCULong _) = [CTypeDef (internalIdent "TexCULong") internalNode]+codeGenIntegralTex (TypeCLLong _) = [CTypeDef (internalIdent "TexCLLong") internalNode]+codeGenIntegralTex (TypeCULLong _) = [CTypeDef (internalIdent "TexCULLong") internalNode]++codeGenIntegralTex (TypeInt _) =+ case F.sizeOf (undefined::Int) of+ 4 -> [CTypeDef (internalIdent "TexInt32") internalNode]+ 8 -> [CTypeDef (internalIdent "TexInt64") internalNode]+ _ -> error "we can never get here"++codeGenIntegralTex (TypeWord _) =+ case F.sizeOf (undefined::Word) of+ 4 -> [CTypeDef (internalIdent "TexWord32") internalNode]+ 8 -> [CTypeDef (internalIdent "TexWord64") internalNode]+ _ -> error "we can never get here"++codeGenFloatingTex :: FloatingType a -> CType+codeGenFloatingTex (TypeFloat _) = [CTypeDef (internalIdent "TexFloat") internalNode]+codeGenFloatingTex (TypeCFloat _) = [CTypeDef (internalIdent "TexCFloat") internalNode]+codeGenFloatingTex (TypeDouble _) = [CTypeDef (internalIdent "TexDouble") internalNode]+codeGenFloatingTex (TypeCDouble _) = [CTypeDef (internalIdent "TexCDouble") internalNode]++-- TLM 2010-06-29:+-- Bool and Char can be implemented once the array types in+-- Data.Array.Accelerate.[CUDA.]Array.Data are made concrete.+--+codeGenNonNumTex :: NonNumType a -> CType+codeGenNonNumTex (TypeBool _) = error "codeGenNonNumTex :: Bool"+codeGenNonNumTex (TypeChar _) = error "codeGenNonNumTex :: Char"+codeGenNonNumTex (TypeCChar _) = [CTypeDef (internalIdent "TexCChar") internalNode]+codeGenNonNumTex (TypeCSChar _) = [CTypeDef (internalIdent "TexCSChar") internalNode]+codeGenNonNumTex (TypeCUChar _) = [CTypeDef (internalIdent "TexCUChar") internalNode]+++-- Scalar Primitives+-- ~~~~~~~~~~~~~~~~~++codeGenPrimConst :: AST.PrimConst a -> CExpr+codeGenPrimConst (AST.PrimMinBound ty) = codeGenMinBound ty+codeGenPrimConst (AST.PrimMaxBound ty) = codeGenMaxBound ty+codeGenPrimConst (AST.PrimPi ty) = codeGenPi ty++codeGenPrim :: AST.PrimFun p -> [CExpr] -> CExpr+codeGenPrim (AST.PrimAdd _) [a,b] = CBinary CAddOp a b internalNode+codeGenPrim (AST.PrimSub _) [a,b] = CBinary CSubOp a b internalNode+codeGenPrim (AST.PrimMul _) [a,b] = CBinary CMulOp a b internalNode+codeGenPrim (AST.PrimNeg _) [a] = CUnary CMinOp a internalNode+codeGenPrim (AST.PrimAbs ty) [a] = codeGenAbs ty a+codeGenPrim (AST.PrimSig ty) [a] = codeGenSig ty a+codeGenPrim (AST.PrimQuot ty) [a,b] = codeGenQuot ty a b+codeGenPrim (AST.PrimRem _) [a,b] = CBinary CRmdOp a b internalNode+codeGenPrim (AST.PrimIDiv _) [a,b] = CBinary CDivOp a b internalNode+codeGenPrim (AST.PrimMod ty) [a,b] = codeGenMod ty a b+codeGenPrim (AST.PrimBAnd _) [a,b] = CBinary CAndOp a b internalNode+codeGenPrim (AST.PrimBOr _) [a,b] = CBinary COrOp a b internalNode+codeGenPrim (AST.PrimBXor _) [a,b] = CBinary CXorOp a b internalNode+codeGenPrim (AST.PrimBNot _) [a] = CUnary CCompOp a internalNode+codeGenPrim (AST.PrimBShiftL _) [a,b] = CBinary CShlOp a b internalNode+codeGenPrim (AST.PrimBShiftR _) [a,b] = CBinary CShrOp a b internalNode+codeGenPrim (AST.PrimBRotateL _) [a,b] = codeGenBRotateL a b+codeGenPrim (AST.PrimBRotateR _) [a,b] = codeGenBRotateR a b+codeGenPrim (AST.PrimFDiv _) [a,b] = CBinary CDivOp a b internalNode+codeGenPrim (AST.PrimRecip ty) [a] = codeGenRecip ty a+codeGenPrim (AST.PrimSin ty) [a] = ccall (FloatingNumType ty) "sin" [a]+codeGenPrim (AST.PrimCos ty) [a] = ccall (FloatingNumType ty) "cos" [a]+codeGenPrim (AST.PrimTan ty) [a] = ccall (FloatingNumType ty) "tan" [a]+codeGenPrim (AST.PrimAsin ty) [a] = ccall (FloatingNumType ty) "asin" [a]+codeGenPrim (AST.PrimAcos ty) [a] = ccall (FloatingNumType ty) "acos" [a]+codeGenPrim (AST.PrimAtan ty) [a] = ccall (FloatingNumType ty) "atan" [a]+codeGenPrim (AST.PrimAsinh ty) [a] = ccall (FloatingNumType ty) "asinh" [a]+codeGenPrim (AST.PrimAcosh ty) [a] = ccall (FloatingNumType ty) "acosh" [a]+codeGenPrim (AST.PrimAtanh ty) [a] = ccall (FloatingNumType ty) "atanh" [a]+codeGenPrim (AST.PrimExpFloating ty) [a] = ccall (FloatingNumType ty) "exp" [a]+codeGenPrim (AST.PrimSqrt ty) [a] = ccall (FloatingNumType ty) "sqrt" [a]+codeGenPrim (AST.PrimLog ty) [a] = ccall (FloatingNumType ty) "log" [a]+codeGenPrim (AST.PrimFPow ty) [a,b] = ccall (FloatingNumType ty) "pow" [a,b]+codeGenPrim (AST.PrimLogBase ty) [a,b] = codeGenLogBase ty a b+codeGenPrim (AST.PrimLt _) [a,b] = CBinary CLeOp a b internalNode+codeGenPrim (AST.PrimGt _) [a,b] = CBinary CGrOp a b internalNode+codeGenPrim (AST.PrimLtEq _) [a,b] = CBinary CLeqOp a b internalNode+codeGenPrim (AST.PrimGtEq _) [a,b] = CBinary CGeqOp a b internalNode+codeGenPrim (AST.PrimEq _) [a,b] = CBinary CEqOp a b internalNode+codeGenPrim (AST.PrimNEq _) [a,b] = CBinary CNeqOp a b internalNode+codeGenPrim (AST.PrimMax ty) [a,b] = codeGenMax ty a b+codeGenPrim (AST.PrimMin ty) [a,b] = codeGenMin ty a b+codeGenPrim AST.PrimLAnd [a,b] = CBinary CLndOp a b internalNode+codeGenPrim AST.PrimLOr [a,b] = CBinary CLorOp a b internalNode+codeGenPrim AST.PrimLNot [a] = CUnary CNegOp a internalNode+codeGenPrim AST.PrimOrd [a] = CCast (CDecl [CTypeSpec (CIntType internalNode)] [] internalNode) a internalNode+codeGenPrim AST.PrimChr [a] = CCast (CDecl [CTypeSpec (CCharType internalNode)] [] internalNode) a internalNode+codeGenPrim AST.PrimRoundFloatInt [a] = CCall (CVar (internalIdent "lroundf") internalNode) [a] internalNode -- TLM: (int) rintf(x) ??+codeGenPrim AST.PrimTruncFloatInt [a] = CCall (CVar (internalIdent "ltruncf") internalNode) [a] internalNode+codeGenPrim AST.PrimIntFloat [a] = CCast (CDecl [CTypeSpec (CFloatType internalNode)] [] internalNode) a internalNode -- TLM: __int2float_[rn,rz,ru,rd](a) ??+codeGenPrim AST.PrimBoolToInt [a] = CCast (CDecl [CTypeSpec (CIntType internalNode)] [] internalNode) a internalNode++-- If the argument lists are not the correct length+codeGenPrim _ _ =+ error "Data.Array.Accelerate.CUDA: inconsistent valuation"+++-- Implementation+--+codeGenConst :: TupleType a -> a -> [CExpr]+codeGenConst UnitTuple _ = []+codeGenConst (SingleTuple ty) c = [codeGenScalar ty c]+codeGenConst (PairTuple ty1 ty0) (cs,c) = codeGenConst ty1 cs ++ codeGenConst ty0 c+++codeGenScalar :: ScalarType a -> a -> CExpr+codeGenScalar (NumScalarType (IntegralNumType ty))+ | IntegralDict <- integralDict ty+ = CConst . flip CIntConst internalNode . cInteger . fromIntegral+codeGenScalar (NumScalarType (FloatingNumType ty))+ | FloatingDict <- floatingDict ty+ = CConst . flip CFloatConst internalNode . cFloat . fromRational . toRational+codeGenScalar (NonNumScalarType (TypeBool _)) = fromBool+codeGenScalar (NonNumScalarType (TypeChar _)) =+ CConst . flip CCharConst internalNode . cChar+codeGenScalar (NonNumScalarType (TypeCChar _)) =+ CConst . flip CCharConst internalNode . cChar . chr . fromIntegral+codeGenScalar (NonNumScalarType (TypeCUChar _)) =+ CConst . flip CCharConst internalNode . cChar . chr . fromIntegral+codeGenScalar (NonNumScalarType (TypeCSChar _)) =+ CConst . flip CCharConst internalNode . cChar . chr . fromIntegral+++codeGenPi :: FloatingType a -> CExpr+codeGenPi ty | FloatingDict <- floatingDict ty+ = codeGenScalar (NumScalarType (FloatingNumType ty)) pi++codeGenMinBound :: BoundedType a -> CExpr+codeGenMinBound (IntegralBoundedType ty)+ | IntegralDict <- integralDict ty+ = codeGenScalar (NumScalarType (IntegralNumType ty)) minBound+codeGenMinBound (NonNumBoundedType ty)+ | NonNumDict <- nonNumDict ty+ = codeGenScalar (NonNumScalarType ty) minBound++codeGenMaxBound :: BoundedType a -> CExpr+codeGenMaxBound (IntegralBoundedType ty)+ | IntegralDict <- integralDict ty+ = codeGenScalar (NumScalarType (IntegralNumType ty)) maxBound+codeGenMaxBound (NonNumBoundedType ty)+ | NonNumDict <- nonNumDict ty+ = codeGenScalar (NonNumScalarType ty) maxBound+++codeGenAbs :: NumType a -> CExpr -> CExpr+codeGenAbs ty@(IntegralNumType _) x = ccall ty "abs" [x]+codeGenAbs ty@(FloatingNumType _) x = ccall ty "fabs" [x]++codeGenSig :: NumType a -> CExpr -> CExpr+codeGenSig ty@(IntegralNumType t) a+ | IntegralDict <- integralDict t+ = CCond (CBinary CGeqOp a (codeGenScalar (NumScalarType ty) 0) internalNode)+ (Just (codeGenScalar (NumScalarType ty) 1))+ (codeGenScalar (NumScalarType ty) 0)+ internalNode+codeGenSig ty@(FloatingNumType t) a+ | FloatingDict <- floatingDict t+ = CCond (CBinary CGeqOp a (codeGenScalar (NumScalarType ty) 0) internalNode)+ (Just (codeGenScalar (NumScalarType ty) 1))+ (codeGenScalar (NumScalarType ty) 0)+ internalNode++codeGenQuot :: IntegralType a -> CExpr -> CExpr -> CExpr+codeGenQuot = error "Data.Array.Accelerate.CUDA.CodeGen: PrimQuot"++codeGenMod :: IntegralType a -> CExpr -> CExpr -> CExpr+codeGenMod = error "Data.Array.Accelerate.CUDA.CodeGen: PrimMod"++-- TLM 2010-06-29:+-- It would be nice we could use something like Language.C.Parser.execParser+-- to suck in the C code directly, instead of storing this long and messy+-- abstract syntax. The problem lies in injecting our `x' and `i' expressions.+--+-- T rotl(T x, int i)+-- {+-- return (i &= 8 * sizeof(x) - 1) == 0 ? x : x << i | x >> 8 * sizeof(x) - i;+-- }+--+codeGenBRotateL :: CExpr -> CExpr -> CExpr+codeGenBRotateL x i =+ CCond (CBinary CEqOp (CAssign CAndAssOp i (CBinary CSubOp (CBinary CMulOp (CConst (CIntConst (cInteger 8) internalNode)) (CSizeofExpr x internalNode) internalNode) (CConst (CIntConst (cInteger 1) internalNode)) internalNode) internalNode) (CConst (CIntConst (cInteger 0) internalNode)) internalNode) (Just x) (CBinary COrOp (CBinary CShlOp x i internalNode) (CBinary CShrOp x (CBinary CSubOp (CBinary CMulOp (CConst (CIntConst (cInteger 8) internalNode)) (CSizeofExpr x internalNode) internalNode) i internalNode) internalNode) internalNode) internalNode++-- T rotr(T x, int i)+-- {+-- return (i &= 8 * sizeof(x) - 1) == 0 ? x : x >> i | x << 8 * sizeof(x) - i;+-- }+--+codeGenBRotateR :: CExpr -> CExpr -> CExpr+codeGenBRotateR x i =+ CCond (CBinary CEqOp (CAssign CAndAssOp i (CBinary CSubOp (CBinary CMulOp (CConst (CIntConst (cInteger 8) internalNode)) (CSizeofExpr x internalNode) internalNode) (CConst (CIntConst (cInteger 1) internalNode)) internalNode) internalNode) (CConst (CIntConst (cInteger 0) internalNode)) internalNode) (Just x) (CBinary COrOp (CBinary CShrOp x i internalNode) (CBinary CShlOp x (CBinary CSubOp (CBinary CMulOp (CConst (CIntConst (cInteger 8) internalNode)) (CSizeofExpr x internalNode) internalNode) i internalNode) internalNode) internalNode) internalNode++codeGenRecip :: FloatingType a -> CExpr -> CExpr+codeGenRecip ty x | FloatingDict <- floatingDict ty+ = CBinary CDivOp (codeGenScalar (NumScalarType (FloatingNumType ty)) 1) x internalNode++codeGenLogBase :: FloatingType a -> CExpr -> CExpr -> CExpr+codeGenLogBase ty x y = let a = ccall (FloatingNumType ty) "log" [x]+ b = ccall (FloatingNumType ty) "log" [y]+ in+ CBinary CDivOp b a internalNode++codeGenMin :: ScalarType a -> CExpr -> CExpr -> CExpr+codeGenMin (NumScalarType ty@(IntegralNumType _)) a b = ccall ty "min" [a,b]+codeGenMin (NumScalarType ty@(FloatingNumType _)) a b = ccall ty "fmin" [a,b]+codeGenMin (NonNumScalarType _) _ _ = undefined++codeGenMax :: ScalarType a -> CExpr -> CExpr -> CExpr+codeGenMax (NumScalarType ty@(IntegralNumType _)) a b = ccall ty "max" [a,b]+codeGenMax (NumScalarType ty@(FloatingNumType _)) a b = ccall ty "fmax" [a,b]+codeGenMax (NonNumScalarType _) _ _ = undefined+++-- Helper Functions+-- ~~~~~~~~~~~~~~~~++ccall :: NumType a -> String -> [CExpr] -> CExpr+ccall (IntegralNumType _) fn args = CCall (CVar (internalIdent fn) internalNode) args internalNode+ccall (FloatingNumType ty) fn args = CCall (CVar (internalIdent (fn `postfix` ty)) internalNode) args internalNode+ where+ postfix :: String -> FloatingType a -> String+ postfix x (TypeFloat _) = x ++ "f"+ postfix x (TypeCFloat _) = x ++ "f"+ postfix x _ = x+
+ Data/Array/Accelerate/CUDA/CodeGen/Data.hs view
@@ -0,0 +1,34 @@+-- |+-- Module : Data.Array.Accelerate.CUDA.CodeGen.Data+-- Copyright : [2008..2010] Manuel M T Chakravarty, Gabriele Keller, Sean Lee, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Manuel M T Chakravarty <chak@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-partable (GHC extensions)+--+-- Common data types for code generation+--++module Data.Array.Accelerate.CUDA.CodeGen.Data+ (+ CType, CUTranslSkel(..)+ )+ where++import Language.C+import Text.PrettyPrint++type CType = [CTypeSpec]+data CUTranslSkel = CUTranslSkel CTranslUnit FilePath++instance Pretty CUTranslSkel where+ pretty (CUTranslSkel code skel) =+ vcat [ include "accelerate_cuda_extras.h"+ , pretty code+ , include skel ]+++include :: String -> Doc+include hdr = text "#include <" <> text hdr <> text ">"+
+ Data/Array/Accelerate/CUDA/CodeGen/Skeleton.hs view
@@ -0,0 +1,150 @@+-- |+-- Module : Data.Array.Accelerate.CUDA.CodeGen.Skeleton+-- Copyright : [2008..2010] Manuel M T Chakravarty, Gabriele Keller, Sean Lee, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Manuel M T Chakravarty <chak@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--+-- Constructors for array computation skeletons+--++module Data.Array.Accelerate.CUDA.CodeGen.Skeleton+ (+ mkFold, mkFoldSeg, mkMap, mkZipWith, mkScanl, mkScanr,+ mkPermute, mkBackpermute, mkIndex, mkReplicate+ )+ where++import Language.C+import Data.Array.Accelerate.CUDA.CodeGen.Data+import Data.Array.Accelerate.CUDA.CodeGen.Util+import Data.Array.Accelerate.CUDA.CodeGen.Tuple++--------------------------------------------------------------------------------+-- Reduction+--------------------------------------------------------------------------------++mkFold :: [CType] -> [CExpr] -> [CExpr] -> CUTranslSkel+mkFold ty identity apply = CUTranslSkel code skel+ where+ skel = "fold.inl"+ code = CTranslUnit+ ( mkTupleTypeAsc 2 ty +++ [ mkIdentity identity+ , mkApply 2 apply ])+ (mkNodeInfo (initPos "fold.cu") (Name 0))++mkFoldSeg :: [CType] -> [CExpr] -> [CExpr] -> CUTranslSkel+mkFoldSeg _ty _identity _apply = undefined+++--------------------------------------------------------------------------------+-- Map+--------------------------------------------------------------------------------++mkMap :: [CType] -> [CType] -> [CExpr] -> CUTranslSkel+mkMap tyOut tyIn0 apply = CUTranslSkel code skel+ where+ skel = "map.inl"+ code = CTranslUnit+ ( mkTupleType Nothing tyOut +++ mkTupleType (Just 0) tyIn0 +++ [ mkApply 1 apply ])+ (mkNodeInfo (initPos "map.cu") (Name 0))+++mkZipWith :: [CType] -> [CType] -> [CType] -> [CExpr] -> CUTranslSkel+mkZipWith tyOut tyIn1 tyIn0 apply = CUTranslSkel code skel+ where+ skel = "zipWith.inl"+ code = CTranslUnit+ ( mkTupleType Nothing tyOut +++ mkTupleType (Just 1) tyIn1 +++ mkTupleType (Just 0) tyIn0 +++ [ mkApply 2 apply ])+ (mkNodeInfo (initPos "zipWith.cu") (Name 0))+++--------------------------------------------------------------------------------+-- Scan+--------------------------------------------------------------------------------++mkScan :: Bool -> [CType] -> [CExpr] -> [CExpr] -> CUTranslSkel+mkScan isBackward ty identity apply =+ CUTranslSkel code skel+ where+ skel | length ty == 1 = "thrust/scan_safe.inl" -- TODO: use fast scan for primitive types+ | otherwise = "thrust/scan_safe.inl"++ code = CTranslUnit+ ( mkTupleTypeAsc 2 ty +++ [ mkIdentity identity+ , mkApply 2 apply+ , mkFlag "reverse" (fromBool isBackward) ])+ (mkNodeInfo (initPos "scan.cu") (Name 0))+++mkScanl :: [CType] -> [CExpr] -> [CExpr] -> CUTranslSkel+mkScanl = mkScan False++mkScanr :: [CType] -> [CExpr] -> [CExpr] -> CUTranslSkel+mkScanr = mkScan True++-- TLM 2010-06-30:+-- Test whether the compiler will use this to avoid branching+--+mkFlag :: String -> CExpr -> CExtDecl+mkFlag name val =+ CDeclExt (CDecl+ [CTypeQual (CAttrQual (CAttr (internalIdent "device") [] internalNode)), CStorageSpec (CStatic internalNode), CTypeQual (CConstQual internalNode), CTypeSpec (CIntType internalNode)]+ [(Just (CDeclr (Just (internalIdent name)) [] Nothing [] internalNode),Just (CInitExpr val internalNode),Nothing)]+ internalNode)+++--------------------------------------------------------------------------------+-- Permutation+--------------------------------------------------------------------------------++mkPermute :: [CType] -> [CExpr] -> [CExpr] -> CUTranslSkel+mkPermute ty combine index = CUTranslSkel code skel+ where+ skel = "permute.inl"+ code = CTranslUnit+ ( mkTupleTypeAsc 2 ty +++ [ mkIgnore (-1)+ , mkIndexFun index+ , mkApply 2 combine ])+ (mkNodeInfo (initPos "permute.cu") (Name 0))++-- TLM 2010-07-10:+-- should generate from Sugar.Ix (or Representation.Ix) notion of ignore+--+mkIgnore :: Integer -> CExtDecl+mkIgnore n =+ CDeclExt+ (CDecl [CTypeQual (CConstQual internalNode),CTypeSpec (CTypeDef (internalIdent "Ix") internalNode)]+ [(Just (CDeclr (Just (internalIdent "ignore")) [] Nothing [] internalNode),Just (CInitExpr (CCast (CDecl [CTypeSpec (CTypeDef (internalIdent "Ix") internalNode)] [] internalNode) (CConst (CIntConst (cInteger n) internalNode)) internalNode) internalNode),Nothing)]+ internalNode)++mkBackpermute :: [CType] -> [CExpr] -> CUTranslSkel+mkBackpermute ty index = CUTranslSkel code skel+ where+ skel = "backpermute.inl"+ code = CTranslUnit+ ( mkTupleTypeAsc 1 ty +++ [ mkIndexFun index ])+ (mkNodeInfo (initPos "backpermute.cu") (Name 0))+++--------------------------------------------------------------------------------+-- Multidimensional Index and Replicate+--------------------------------------------------------------------------------++mkIndex :: [CType] -> [CExpr] -> CUTranslSkel+mkIndex _ty _slix = undefined++mkReplicate :: [CType] -> [CExpr] -> CUTranslSkel+mkReplicate _ty _slix = undefined+
+ Data/Array/Accelerate/CUDA/CodeGen/Tuple.hs view
@@ -0,0 +1,87 @@+-- |+-- Module : Data.Array.Accelerate.CUDA.CodeGen.Tuple+-- Copyright : [2008..2010] Manuel M T Chakravarty, Gabriele Keller, Sean Lee, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Manuel M T Chakravarty <chak@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-partable (GHC extensions)+--++module Data.Array.Accelerate.CUDA.CodeGen.Tuple (mkTupleType, mkTupleTypeAsc)+ where++import Language.C+import Data.Array.Accelerate.CUDA.CodeGen.Data+import Data.Array.Accelerate.CUDA.CodeGen.Util+++mkTupleType :: Maybe Int -> [CType] -> [CExtDecl]+mkTupleType subscript ty = types ++ [accessor]+ where+ n = length ty+ base = maybe "Out" (\p -> "In" ++ show p) subscript+ accessor = maybe (mkSet n) (mkGet n) subscript+ types+ | n <= 1 = [ mkTypedef ("Ty" ++ base) False (head ty), mkTypedef ("Arr" ++ base) True (head ty)]+ | otherwise = [ mkStruct ("Ty" ++ base) False ty, mkStruct ("Arr" ++ base) True ty]++-- A variant of tuple generation for associative array computations, generating+-- base get and set functions, and the given number of type synonyms.+--+mkTupleTypeAsc :: Int -> [CType] -> [CExtDecl]+mkTupleTypeAsc syn ty = types ++ synonyms ++ [mkSet n, mkGet n 0]+ where+ n = length ty+ synonyms = concat . take syn . flip map ([0..] :: [Int]) $ \v ->+ [ mkTypedef ("TyIn" ++ show v) False [CTypeDef (internalIdent "TyOut") internalNode]+ , mkTypedef ("ArrIn" ++ show v) False [CTypeDef (internalIdent "ArrOut") internalNode] ]+ types+ | n <= 1 = [ mkTypedef "TyOut" False (head ty), mkTypedef "ArrOut" True (head ty)]+ | otherwise = [ mkStruct "TyOut" False ty, mkStruct "ArrOut" True ty]+++-- Getter and setter functions for reading and writing (respectively) to global+-- device arrays. Since arrays of tuples are stored as tuples of arrays, we+-- retrieve each component separately and pack into a local structure.+--+-- This unfortunately also means that we can not declare an overloaded indexing+-- operator[], since it is not possible to return an l-value to the discrete+-- component arrays (we could read, but not write).+--+-- NOTE: The Accelerate language uses snoc based tuple projection, so the last+-- field of the structure is named 'a' instead of the first, while the+-- arrays themselves are still stored "in order".+--+mkGet :: Int -> Int -> CExtDecl+mkGet n prj =+ CFDefExt+ (CFunDef+ [CStorageSpec (CStatic internalNode), CTypeQual (CInlineQual internalNode), CTypeQual (CAttrQual (CAttr (internalIdent "device") [] internalNode)), CTypeSpec (CTypeDef (internalIdent ("TyIn" ++ show prj)) internalNode)]+ (CDeclr (Just (internalIdent ("get" ++ show prj))) [CFunDeclr (Right ([CDecl [CTypeQual (CConstQual internalNode), CTypeSpec (CTypeDef (internalIdent ("ArrIn" ++ show prj)) internalNode)] [(Just (CDeclr (Just arrIn) [] Nothing [] internalNode), Nothing, Nothing)] internalNode, CDecl [CTypeQual (CConstQual internalNode), CTypeSpec (CTypeDef (internalIdent "Ix") internalNode)] [(Just (CDeclr (Just (internalIdent "idx")) [] Nothing [] internalNode), Nothing, Nothing)] internalNode], False)) [] internalNode] Nothing [] internalNode)+ []+ (CCompound [] [CBlockDecl (CDecl [CTypeSpec (CTypeDef (internalIdent ("TyIn" ++ show prj)) internalNode)] [(Just (CDeclr (Just (internalIdent "x")) [] Nothing [] internalNode),Just initList,Nothing)] internalNode),CBlockStmt (CReturn (Just (CVar (internalIdent "x") internalNode)) internalNode)] internalNode)+ internalNode)+ where+ arrIn = internalIdent ("d_in" ++ show prj)+ initList+ | n <= 1 = CInitExpr (CIndex (CVar arrIn internalNode) (CVar (internalIdent "idx") internalNode) internalNode) internalNode+ | otherwise = flip CInitList internalNode . reverse . take n . flip map (enumFrom 'a') $ \v ->+ ([], CInitExpr (CIndex (CMember (CVar arrIn internalNode) (internalIdent [v]) False internalNode) (CVar (internalIdent "idx") internalNode) internalNode) internalNode)+++mkSet :: Int -> CExtDecl+mkSet n =+ CFDefExt+ (CFunDef+ [CStorageSpec (CStatic internalNode),CTypeQual (CInlineQual internalNode),CTypeQual (CAttrQual (CAttr (internalIdent "device") [] internalNode)),CTypeSpec (CVoidType internalNode)]+ (CDeclr (Just (internalIdent "set")) [CFunDeclr (Right ([CDecl [CTypeSpec (CTypeDef (internalIdent "ArrOut") internalNode)] [(Just (CDeclr (Just (internalIdent "d_out")) [] Nothing [] internalNode),Nothing,Nothing)] internalNode,CDecl [CTypeQual (CConstQual internalNode),CTypeSpec (CTypeDef (internalIdent "Ix") internalNode)] [(Just (CDeclr (Just (internalIdent "idx")) [] Nothing [] internalNode),Nothing,Nothing)] internalNode,CDecl [CTypeQual (CConstQual internalNode),CTypeSpec (CTypeDef (internalIdent "TyOut") internalNode)] [(Just (CDeclr (Just (internalIdent "val")) [] Nothing [] internalNode),Nothing,Nothing)] internalNode],False)) [] internalNode] Nothing [] internalNode)+ []+ (CCompound [] assignList internalNode)+ internalNode)+ where+ assignList+ | n <= 1 = [CBlockStmt (CExpr (Just (CAssign CAssignOp (CIndex (CVar (internalIdent "d_out") internalNode) (CVar (internalIdent "idx") internalNode) internalNode) (CVar (internalIdent "val") internalNode) internalNode)) internalNode)]+ | otherwise = reverse . take n . flip map (enumFrom 'a') $ \v ->+ CBlockStmt (CExpr (Just (CAssign CAssignOp (CIndex (CMember (CVar (internalIdent "d_out") internalNode) (internalIdent [v]) False internalNode) (CVar (internalIdent "idx") internalNode) internalNode) (CMember (CVar (internalIdent "val") internalNode) (internalIdent [v]) False internalNode) internalNode)) internalNode)+
+ Data/Array/Accelerate/CUDA/CodeGen/Util.hs view
@@ -0,0 +1,102 @@+-- |+-- Module : Data.Array.Accelerate.CUDA.CodeGen.Util+-- Copyright : [2008..2010] Manuel M T Chakravarty, Gabriele Keller, Sean Lee, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Manuel M T Chakravarty <chak@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-partable (GHC extensions)+--++module Data.Array.Accelerate.CUDA.CodeGen.Util+ where++import Language.C+import Data.Array.Accelerate.CUDA.CodeGen.Data+++fromBool :: Bool -> CExpr+fromBool True = CConst $ CIntConst (cInteger 1) internalNode+fromBool False = CConst $ CIntConst (cInteger 0) internalNode+++-- typedef ty (*?) var;+--+mkTypedef :: String -> Bool -> CType -> CExtDecl+mkTypedef var ptr ty =+ CDeclExt (CDecl (CStorageSpec (CTypedef internalNode) : map CTypeSpec ty) [(Just (CDeclr (Just (internalIdent var)) [CPtrDeclr [] internalNode | ptr] Nothing [] internalNode), Nothing, Nothing)] internalNode)+++-- typedef struct {+-- ... ty1 (*?) b; ty0 (*?) a;+-- } var;+--+-- NOTE: The Accelerate language uses snoc based tuple projection, so the last+-- field of the structure is named 'a' instead of the first.+--+mkStruct :: String -> Bool -> [CType] -> CExtDecl+mkStruct name ptr types =+ CDeclExt (CDecl [ CStorageSpec (CTypedef internalNode) , CTypeSpec (CSUType (CStruct CStructTag Nothing (Just (zipWith field names types)) [] internalNode) internalNode)] [(Just (CDeclr (Just (internalIdent name)) [] Nothing [] internalNode),Nothing,Nothing)] internalNode)+ where+ names = reverse . take (length types) $ enumFrom 'a'+ field v ty = CDecl (map CTypeSpec ty) [(Just (CDeclr (Just (internalIdent [v])) [CPtrDeclr [] internalNode | ptr] Nothing [] internalNode),Nothing,Nothing)] internalNode+++-- typedef struct __attribute__((aligned(n * sizeof(ty)))) {+-- ty [x, y, z, w];+-- } var;+--+mkTyVector :: String -> Int -> CType -> CExtDecl+mkTyVector var n ty =+ CDeclExt (CDecl [ CStorageSpec (CTypedef internalNode) , CTypeSpec (CSUType (CStruct CStructTag Nothing (Just [CDecl (map CTypeSpec ty) fields internalNode]) [CAttr (internalIdent "aligned") [CBinary CMulOp (CConst (CIntConst (cInteger (toInteger n)) internalNode)) (CSizeofType (CDecl (map CTypeSpec ty) [] internalNode) internalNode) internalNode] internalNode] internalNode) internalNode)] [ (Just (CDeclr (Just (internalIdent var)) [] Nothing [] internalNode), Nothing, Nothing)] internalNode)+ where+ fields = take n . flip map "xyzw" $ \f ->+ (Just (CDeclr (Just (internalIdent [f])) [] Nothing [] internalNode), Nothing, Nothing)+++-- static inline __attribute__((device)) TyOut identity()+-- {+-- return expr;+-- }+--+mkIdentity :: [CExpr] -> CExtDecl+mkIdentity expr =+ CFDefExt (CFunDef [CStorageSpec (CStatic internalNode),CTypeQual (CInlineQual internalNode),CTypeQual (CAttrQual (CAttr (builtinIdent "device") [] internalNode)),CTypeSpec (CTypeDef (internalIdent "TyOut") internalNode)] (CDeclr (Just (internalIdent "identity")) [CFunDeclr (Right ([],False)) [] internalNode] Nothing [] internalNode) [] (CCompound [] [CBlockDecl (CDecl [CTypeSpec (CTypeDef (internalIdent "TyOut") internalNode)] [(Just (CDeclr (Just (internalIdent "x")) [] Nothing [] internalNode),Just (mkInitList expr),Nothing)] internalNode),CBlockStmt (CReturn (Just (CVar (internalIdent "x") internalNode)) internalNode)] internalNode) internalNode)+++-- static inline __attribute__((device)) TyOut+-- apply(..., const TyIn1 x1, const TyIn0 x0)+-- {+-- TyOut x; x.a = x0; x.b = x1; ...+-- return x;+-- }+--+mkApply :: Int -> [CExpr] -> CExtDecl+mkApply argc expr =+ CFDefExt (CFunDef [CStorageSpec (CStatic internalNode),CTypeQual (CInlineQual internalNode),CTypeQual (CAttrQual (CAttr (builtinIdent "device") [] internalNode)),CTypeSpec (CTypeDef (internalIdent "TyOut") internalNode)] (CDeclr (Just (internalIdent "apply")) [CFunDeclr (Right (argv,False)) [] internalNode] Nothing [] internalNode) [] (CCompound [] [CBlockDecl (CDecl [CTypeSpec (CTypeDef (internalIdent "TyOut") internalNode)] [(Just (CDeclr (Just (internalIdent "x")) [] Nothing [] internalNode),Just (mkInitList expr),Nothing)] internalNode),CBlockStmt (CReturn (Just (CVar (internalIdent "x") internalNode)) internalNode)] internalNode) internalNode)+ where+ argv = reverse . take argc . flip map (enumFrom 0 :: [Int]) $ \x ->+ let ty = "TyIn" ++ show x+ var = 'x' : show x+ in+ CDecl [CTypeQual (CConstQual internalNode), CTypeSpec (CTypeDef (internalIdent ty) internalNode)]+ [(Just (CDeclr (Just (internalIdent var)) [] Nothing [] internalNode), Nothing, Nothing)]+ internalNode++-- Not strictly necessary, just attention to detail+--+mkInitList :: [CExpr] -> CInit+mkInitList [x] = CInitExpr x internalNode+mkInitList xs = CInitList (map (\e -> ([],CInitExpr e internalNode)) xs) internalNode+++-- static inline __attribute__((device)) Ix+-- project(const Ix x0)+-- {+-- return expr;+-- }+--+mkIndexFun :: [CExpr] -> CExtDecl+mkIndexFun [expr] = CFDefExt (CFunDef [CStorageSpec (CStatic internalNode),CTypeQual (CInlineQual internalNode),CTypeQual (CAttrQual (CAttr (builtinIdent "device") [] internalNode)),CTypeSpec (CTypeDef (internalIdent "Ix") internalNode)] (CDeclr (Just (internalIdent "project")) [CFunDeclr (Right ([CDecl [CTypeQual (CConstQual internalNode),CTypeSpec (CTypeDef (internalIdent "Ix") internalNode)] [(Just (CDeclr (Just (internalIdent "x0")) [] Nothing [] internalNode),Nothing,Nothing)] internalNode],False)) [] internalNode] Nothing [] internalNode) [] (CCompound [] [CBlockStmt (CReturn (Just expr) internalNode)] internalNode) internalNode)+mkIndexFun _ = error "mkIndexFun: internal error"+
+ Data/Array/Accelerate/CUDA/Compile.hs view
@@ -0,0 +1,177 @@+{-# LANGUAGE GADTs #-}+-- |+-- Module : Data.Array.Accelerate.CUDA.Compile+-- Copyright : [2008..2010] Manuel M T Chakravarty, Gabriele Keller, Sean Lee, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Manuel M T Chakravarty <chak@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-partable (GHC extensions)+--++module Data.Array.Accelerate.CUDA.Compile (compileAcc)+ where++import Prelude hiding (id, (.), mod)+import Control.Category++import Data.Maybe+import Control.Monad+import Control.Monad.IO.Class+import Control.Exception+import Control.Applicative hiding (Const)+import Language.C+import Text.PrettyPrint+import qualified Data.Map as M++import System.Directory+import System.FilePath+import System.Posix.Process+import System.IO++import Data.Array.Accelerate.AST+import Data.Array.Accelerate.Tuple+import Data.Array.Accelerate.Array.Representation+import Data.Array.Accelerate.Array.Sugar (Array(..))+import Data.Array.Accelerate.CUDA.State+import Data.Array.Accelerate.CUDA.CodeGen+import Data.Array.Accelerate.CUDA.Array.Data+import Data.Array.Accelerate.CUDA.Analysis.Hash++import Foreign.CUDA.Analysis.Device++import Paths_accelerate (getDataDir)+++-- | Initiate code generation, compilation, and data transfer for an array+-- expression+--+compileAcc :: OpenAcc aenv a -> CIO ()+compileAcc (Use (Array sh ad)) =+ let n = size sh+ in do+ mallocArray ad n+ pokeArrayAsync ad n Nothing++compileAcc (Let a1 a2) = compileAcc a1 >> compileAcc a2+compileAcc (Let2 a1 a2) = compileAcc a1 >> compileAcc a2+compileAcc (Avar _) = return ()+compileAcc (Unit e1) = compileExp e1+compileAcc (Reshape e1 a1) = compileExp e1 >> compileAcc a1++compileAcc op@(Replicate _ e1 a1) = compileExp e1 >> compileAcc a1 >> compile op+compileAcc op@(Index _ a1 e1) = compileAcc a1 >> compileExp e1 >> compile op+compileAcc op@(Map f1 a1) = compileFun f1 >> compileAcc a1 >> compile op+compileAcc op@(ZipWith f1 a1 a2) = compileFun f1 >> compileAcc a1 >> compileAcc a2 >> compile op+compileAcc op@(Fold f1 e1 a1) = compileFun f1 >> compileExp e1 >> compileAcc a1 >> compile op+compileAcc op@(Scanl f1 e1 a1) = compileFun f1 >> compileExp e1 >> compileAcc a1 >> compile op+compileAcc op@(Scanr f1 e1 a1) = compileFun f1 >> compileExp e1 >> compileAcc a1 >> compile op+compileAcc op@(Backpermute e1 f1 a1) = compileExp e1 >> compileFun f1 >> compileAcc a1 >> compile op+compileAcc op@(Permute f1 a1 f2 a2) = compileFun f1 >> compileAcc a1 >> compileFun f2 >> compileAcc a2 >> compile op+compileAcc op@(FoldSeg f1 e1 a1 a2) = compileFun f1 >> compileExp e1 >> compileAcc a1 >> compileAcc a2 >> compile op+++-- | Lift array expressions out of closed functions for code generation+--+compileFun :: OpenFun env aenv t -> CIO ()+compileFun (Body e) = compileExp e+compileFun (Lam f) = compileFun f+++-- | Lift array computations out of scalar expressions for code generation. The+-- array expression must not contain any free scalar variables.+--+compileExp :: OpenExp env aenv a -> CIO ()+compileExp (Tuple t) = compileTup t+compileExp (Prj _ e1) = compileExp e1+compileExp (PrimApp _ e1) = compileExp e1+compileExp (Cond e1 e2 e3) = compileExp e1 >> compileExp e2 >> compileExp e3+compileExp (IndexScalar a1 e1) = compileAcc a1 >> compileExp e1+compileExp (Shape a1) = compileAcc a1+compileExp _ = return ()++compileTup :: Tuple (OpenExp env aenv) a -> CIO ()+compileTup NilTup = return ()+compileTup (t `SnocTup` e) = compileExp e >> compileTup t+++-- | Generate and compile code for a single open array expression+--+compile :: OpenAcc aenv a -> CIO ()+compile acc = do+ let key = accToKey acc+ compiled <- M.member key <$> getM kernelEntry+ unless compiled $ do+ nvcc <- fromMaybe (error "nvcc: command not found") <$> liftIO (findExecutable "nvcc")+ dir <- getM outputDir+ cufile <- outputName acc (dir </> "dragon.cu") -- here be dragons!+ flags <- compileFlags cufile+ pid <- liftIO . withFilePath dir $ do+ writeCode cufile (codeGenAcc acc)+ forkProcess $ executeFile nvcc False flags Nothing++ modM kernelEntry $ M.insert key (KernelEntry cufile (Left pid))+++-- Write the generated code to file+--+writeCode :: FilePath -> CUTranslSkel -> IO ()+writeCode f code =+ withFile f WriteMode $ \hdl ->+ printDoc PageMode hdl (pretty code)+++-- stolen from $fptools/ghc/compiler/utils/Pretty.lhs+--+-- This code has a BSD-style license+--+printDoc :: Mode -> Handle -> Doc -> IO ()+printDoc m hdl doc = do+ fullRender m cols 1.5 put done doc+ hFlush hdl+ where+ put (Chr c) next = hPutChar hdl c >> next+ put (Str s) next = hPutStr hdl s >> next+ put (PStr s) next = hPutStr hdl s >> next++ done = hPutChar hdl '\n'+ cols = 100+++-- Determine the appropriate command line flags to pass to the compiler process+--+compileFlags :: FilePath -> CIO [String]+compileFlags cufile = do+ arch <- computeCapability <$> getM deviceProps+ ddir <- liftIO getDataDir+ return [ "-I.", "-I", ddir+ , "-O2", "--compiler-options", "-fno-strict-aliasing"+ , "-arch=sm_" ++ show (round (arch * 10) :: Int)+ , "-DUNIX"+ , "-cubin"+ , takeFileName cufile ]+++-- Execute the IO action under the given directory+--+withFilePath :: FilePath -> IO a -> IO a+withFilePath fp action =+ bracket getCurrentDirectory setCurrentDirectory . const $ do+ setCurrentDirectory fp+ action+++-- Return the output filename of the generated CUDA code+--+-- In future, we hope that this is a unique filename based on the function+-- itself, but for now it is just a unique filename.+--+outputName :: OpenAcc aenv a -> FilePath -> CIO FilePath+outputName acc cufile = do+ n <- freshVar+ x <- liftIO $ doesFileExist (base ++ show n <.> suffix)+ if x then outputName acc cufile+ else return (base ++ show n <.> suffix)+ where+ (base,suffix) = splitExtension cufile+
+ Data/Array/Accelerate/CUDA/Execute.hs view
@@ -0,0 +1,381 @@+{-# LANGUAGE GADTs, TupleSections #-}+-- |+-- Module : Data.Array.Accelerate.CUDA.Execute+-- Copyright : [2008..2010] Manuel M T Chakravarty, Gabriele Keller, Sean Lee, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Manuel M T Chakravarty <chak@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-partable (GHC extensions)+--++module Data.Array.Accelerate.CUDA.Execute (executeAcc)+ where++import Prelude hiding (id, (.), mod, sum)+import Control.Category++import Data.Maybe+import Control.Monad+import Control.Monad.Trans+import Control.Applicative hiding (Const)+import qualified Data.Map as M++import System.FilePath+import System.Posix.Process+import System.Exit (ExitCode(..))+import System.Posix.Types (ProcessID)++import Data.Array.Accelerate.AST+import Data.Array.Accelerate.Tuple+import Data.Array.Accelerate.Array.Data+import Data.Array.Accelerate.Array.Representation+import Data.Array.Accelerate.Array.Sugar (Array(..))+import qualified Data.Array.Accelerate.Array.Sugar as Sugar+import qualified Data.Array.Accelerate.Interpreter as I++import Data.Array.Accelerate.CUDA.State+import Data.Array.Accelerate.CUDA.Array.Data+import Data.Array.Accelerate.CUDA.Analysis.Hash+import Data.Array.Accelerate.CUDA.Analysis.Launch++import qualified Foreign.CUDA.Driver as CUDA+++-- Expression evaluation+-- ~~~~~~~~~~~~~~~~~~~~~++-- Evaluate a closed scalar expression. Expressions are evaluated on the host,+-- but may require some interaction with the device (such as array indexing).+--+-- TLM 2010-07-13:+-- We sneakily use the Interpreter backend for primitive operations, but maybe+-- we don't want to...?+--+executeExp :: Exp aenv t -> Val aenv -> CIO t+executeExp e = executeOpenExp e Empty++executeOpenExp :: OpenExp env aenv t -> Val env -> Val aenv -> CIO t+executeOpenExp (Var idx) env _ = return . Sugar.toElem $ prj idx env+executeOpenExp (Const c) _ _ = return $ Sugar.toElem c+executeOpenExp (PrimConst c) _ _ = return $ I.evalPrimConst c+executeOpenExp (PrimApp fun arg) env aenv = I.evalPrim fun <$> executeOpenExp arg env aenv+executeOpenExp (Prj idx e) env aenv = I.evalPrj idx . fromTuple <$> executeOpenExp e env aenv+executeOpenExp (Tuple tup) env aenv = toTuple <$> executeTuple tup env aenv+executeOpenExp (IndexScalar a e) env aenv = do+ (Array sh ad) <- executeOpenAcc a aenv+ ix <- executeOpenExp e env aenv+ Sugar.toElem <$> ad `indexArray` index sh (Sugar.fromElem ix)++executeOpenExp (Shape a) _ aenv = do+ (Array sh _) <- executeOpenAcc a aenv+ return (Sugar.toElem sh)++executeOpenExp (Cond c t e) env aenv = do+ p <- executeOpenExp c env aenv+ if p then executeOpenExp t env aenv+ else executeOpenExp e env aenv+++executeTuple :: Tuple (OpenExp env aenv) t -> Val env -> Val aenv -> CIO t+executeTuple NilTup _ _ = return ()+executeTuple (tup `SnocTup` e) env aenv = (,) <$> executeTuple tup env aenv <*> executeOpenExp e env aenv+++-- Array evaluation+-- ~~~~~~~~~~~~~~~++-- | Execute a closed array expression+--+executeAcc :: Acc a -> CIO a+executeAcc acc = executeOpenAcc acc Empty++-- |+-- Execute an embedded array program using the CUDA backend. The function will+-- block if the compilation has not yet completed, but subsequent invocations of+-- the same kernel will be able to extract the loaded kernel directly.+--+executeOpenAcc :: OpenAcc aenv a -> Val aenv -> CIO a+executeOpenAcc (Use xs) _env = return xs+executeOpenAcc (Avar ix) env = return $ prj ix env+executeOpenAcc (Let x y) env = do+ ax <- executeOpenAcc x env+ executeOpenAcc y (env `Push` ax)++executeOpenAcc (Let2 x y) env = do+ (ax1,ax2) <- executeOpenAcc x env+ executeOpenAcc y (env `Push` ax1 `Push` ax2)++executeOpenAcc (Unit e) env = do+ v <- executeExp e env+ let ad = fst . runArrayData $ (,undefined) <$> do+ arr <- newArrayData 1+ writeArrayData arr 0 (Sugar.fromElem v)+ return arr++ mallocArray ad 1+ pokeArrayAsync ad 1 Nothing+ return (Array (Sugar.fromElem ()) ad)+++executeOpenAcc acc env = do+ krn <- fromMaybe (error "code generation failed") . M.lookup key <$> getM kernelEntry+ mdl <- either' (get kernelStatus krn) return $ \pid -> do+ liftIO (waitFor pid)+ mdl <- liftIO $ CUDA.loadFile (get kernelName krn `replaceExtension` ".cubin")+ modM kernelEntry $ M.insert key (set kernelStatus (Right mdl) krn)+ return mdl++ -- determine dispatch pattern, extract parameters, allocate storage, run+ --+ dispatch acc env mdl++ where+ key = accToKey acc+ either' e r l = either l r e+++-- Dispatch+-- ~~~~~~~~++data FVar where+ FArr :: Array dim e -> FVar++-- Lift free array variables out of scalar computations. Returns a list of the+-- arrays in the order that they are encountered, which also corresponds to the+-- texture reference index they should be bound to.+--+liftFun :: OpenFun env aenv a -> Val aenv -> CIO [FVar]+liftFun (Body e) = liftExp e+liftFun (Lam f) = liftFun f++liftExp :: OpenExp env aenv a -> Val aenv -> CIO [FVar]+liftExp (Tuple t) aenv = liftTup t aenv+liftExp (PrimApp _ e) aenv = liftExp e aenv+liftExp (Cond e1 e2 e3) aenv = concat <$> sequence [liftExp e1 aenv, liftExp e2 aenv, liftExp e3 aenv]+liftExp (IndexScalar a e) aenv = (:) . FArr <$> executeOpenAcc a aenv <*> liftExp e aenv+liftExp _ _ =+ return []++liftTup :: Tuple (OpenExp env aenv) a -> Val aenv -> CIO [FVar]+liftTup NilTup _ = return []+liftTup (t `SnocTup` e) aenv = (++) <$> liftTup t aenv <*> liftExp e aenv+++-- Extract texture references from the compiled module and bind an array to it+--+bind :: CUDA.Module -> [FVar] -> CIO [CUDA.FunParam]+bind mdl var =+ let tex n (FArr (Array sh ad)) = textureRefs ad mdl (size sh) n+ in concat <$> zipWithM tex [0..] var++release :: [FVar] -> CIO ()+release = mapM_ (\(FArr (Array _ ad)) -> freeArray ad)+++-- Setup and initiate the computation. This may require several kernel launches.+--+-- A NOTE ON TUPLES TYPES+--+-- The astute reader may be wondering, if arrays of tuples are stored as a+-- tuple of arrays, how exactly are we telling the kernel function about this?+--+-- From Haskell land, the tuple components are passed to the kernel function+-- individually. The C function, however, interprets these into a structure of+-- pointers. While this is a nasty sleight-of-hand, it should indeed be safe.+-- Pointer types will all have the same size and alignment, and C structures+-- are defined to keep their fields adjacent in memory (modulo alignment+-- restrictions, which don't concern us).+--+dispatch :: OpenAcc aenv a -> Val aenv -> CUDA.Module -> CIO a+dispatch acc@(Map f ad) env mdl = do+ fn <- liftIO $ CUDA.getFun mdl "map"+ (Array sh in0) <- executeOpenAcc ad env+ let res@(Array sh' out) = newArray (Sugar.toElem sh)+ n = size sh'++ mallocArray out n+ d_out <- devicePtrs out+ d_in0 <- devicePtrs in0+ f_var <- liftFun f env+ t_var <- bind mdl f_var++ launch acc n fn (d_out ++ d_in0 ++ t_var ++ [CUDA.IArg n])+ freeArray in0+ release f_var+ return res++dispatch acc@(ZipWith f ad1 ad0) env mdl = do+ fn <- liftIO $ CUDA.getFun mdl "zipWith"+ (Array sh1 in1) <- executeOpenAcc ad1 env+ (Array sh0 in0) <- executeOpenAcc ad0 env+ let res@(Array sh' out) = newArray (Sugar.toElem (sh0 `intersect` sh1))+ n = size sh'++ mallocArray out n+ d_out <- devicePtrs out+ d_in1 <- devicePtrs in1+ d_in0 <- devicePtrs in0+ f_var <- liftFun f env+ t_var <- bind mdl f_var++ launch acc n fn (d_out ++ d_in1 ++ d_in0 ++ t_var ++ [CUDA.IArg n])+ freeArray in0+ freeArray in1+ release f_var+ return res++dispatch acc@(Fold f x ad) env mdl = do+ fn <- liftIO $ CUDA.getFun mdl "fold"+ (Array sh in0) <- executeOpenAcc ad env+ (cta,grid,smem) <- launchConfig acc (size sh) fn+ let res@(Array _ out) = newArray grid++ mallocArray out grid+ d_out <- devicePtrs out+ d_in0 <- devicePtrs in0+ f_arr <- liftFun f env+ t_var <- bind mdl f_arr++ launch' (cta,grid,smem) fn (d_out ++ d_in0 ++ t_var ++ [CUDA.IArg (size sh)])+ freeArray in0+ release f_arr+ if grid > 1 then dispatch (Fold f x (Use res)) env mdl+ else return (Array (Sugar.fromElem ()) out)++dispatch acc@(Scanl _ _ _) env mdl = dispatchScan acc env mdl+dispatch acc@(Scanr _ _ _) env mdl = dispatchScan acc env mdl++dispatch acc@(Permute f1 df f2 ad) env mdl = do+ fn <- liftIO $ CUDA.getFun mdl "permute"+ (Array sh def) <- executeOpenAcc df env+ (Array sh' in0) <- executeOpenAcc ad env+ let res@(Array _ out) = newArray (Sugar.toElem sh)+ n = size sh'++ mallocArray out n+ copyArray def out n+ d_out <- devicePtrs out+ d_in0 <- devicePtrs in0+ f_arr <- (++) <$> liftFun f1 env <*> liftFun f2 env+ t_var <- bind mdl f_arr++ launch acc n fn (d_out ++ d_in0 ++ t_var ++ [CUDA.IArg n])+ freeArray def+ freeArray in0+ release f_arr+ return res++dispatch acc@(Backpermute e f ad) env mdl = do+ fn <- liftIO $ CUDA.getFun mdl "backpermute"+ sh <- executeExp e env+ (Array _ in0) <- executeOpenAcc ad env+ let res@(Array sh' out) = newArray sh+ n = size sh'++ mallocArray out n+ d_out <- devicePtrs out+ d_in0 <- devicePtrs in0+ f_arr <- liftFun f env+ t_var <- bind mdl f_arr++ launch acc n fn (d_out ++ d_in0 ++ t_var ++ [CUDA.IArg n])+ freeArray in0+ release f_arr+ return res++dispatch _ _ _ =+ error "Data.Array.Accelerate.CUDA: dispatch: internal error"+++-- Unified dispatch handler for left/right scan.+--+-- TLM 2010-07-02:+-- This is a little awkward. At its core we have an inclusive scan routine,+-- whereas accelerate actually returns an exclusive scan result. Multi-block+-- arrays require the inclusive scan when calculating the partial block sums,+-- which are then added to every element of an interval. Single-block arrays+-- on the other hand need to be "converted" to an exclusive result in the+-- second pass.+--+-- This optimised could be implemented by enabling some some extra code to the+-- skeleton, and dispatching accordingly.+--+dispatchScan :: OpenAcc aenv a -> Val aenv -> CUDA.Module -> CIO a+dispatchScan (Scanr f x ad) env mdl = dispatchScan (Scanl f x ad) env mdl+dispatchScan acc@(Scanl f _ ad) env mdl = do+ fscan <- liftIO $ CUDA.getFun mdl "inclusive_scan"+ fadd <- liftIO $ CUDA.getFun mdl "exclusive_update"+ (Array sh in0) <- executeOpenAcc ad env+ (cta,grid,smem) <- launchConfig acc (size sh) fscan+ let a_out@(Array _ out) = newArray (Sugar.toElem sh)+ a_sum@(Array _ sum) = newArray ()+ a_bks@(Array _ bks) = newArray grid+ n = size sh+ units = (n + cta - 1) `div` cta+ interval = cta * ((units + grid - 1) `div` grid)++ unify :: Array dim e -> Array dim' e -> CIO ()+ unify _ _ = return ()++ unify a_sum a_bks -- TLM: *cough*++ mallocArray out n+ mallocArray sum 1+ mallocArray bks grid+ d_out <- devicePtrs out+ d_in0 <- devicePtrs in0+ d_bks <- devicePtrs bks+ d_sum <- devicePtrs sum+ f_arr <- liftFun f env+ t_var <- bind mdl f_arr++ launch' (cta,grid,smem) fscan (d_out ++ d_in0 ++ d_bks ++ t_var ++ map CUDA.IArg [n,interval])+ launch' (cta,1,smem) fscan (d_bks ++ d_bks ++ d_sum ++ map CUDA.IArg [grid,interval])+ launch' (cta,grid,smem) fadd (d_out ++ d_bks ++ map CUDA.IArg [n,interval])++ freeArray in0+ freeArray bks+ return (a_out, a_sum)++dispatchScan _ _ _ =+ error "Data.Array.Accelerate.CUDA: internal error"+++-- Initiate the device computation. The first version selects launch parameters+-- automatically, the second requires them explicitly. This tuple contains+-- threads per block, grid size, and dynamic shared memory, respectively.+--+launch :: OpenAcc aenv a -> Int -> CUDA.Fun -> [CUDA.FunParam] -> CIO ()+launch acc n fn args =+ launchConfig acc n fn >>= \cfg ->+ launch' cfg fn args++launch' :: (Int,Int,Integer) -> CUDA.Fun -> [CUDA.FunParam] -> CIO ()+launch' (cta,grid,smem) fn args =+ liftIO $ do+ CUDA.setParams fn args+ CUDA.setSharedSize fn smem+ CUDA.setBlockShape fn (cta,1,1)+ CUDA.launch fn (grid,1) Nothing+++-- Create a new array (obviously...)+--+{-# INLINE newArray #-}+newArray :: (Sugar.Ix dim, Sugar.Elem e) => dim -> Array dim e+newArray sh = ad `seq` Array (Sugar.fromElem sh) ad+ where+ -- FIXME: small arrays are relocated by the GC+ ad = fst . runArrayData $ (,undefined) <$> newArrayData (1024 `max` Sugar.size sh)+++-- | Wait for the compilation process to finish+--+waitFor :: ProcessID -> IO ()+waitFor pid = do+ status <- getProcessStatus True True pid+ case status of+ Just (Exited ExitSuccess) -> return ()+ _ -> error $ "nvcc (" ++ shows pid ") terminated abnormally"+
+ Data/Array/Accelerate/CUDA/State.hs view
@@ -0,0 +1,174 @@+{-# LANGUAGE TemplateHaskell, TupleSections, TypeOperators #-}+-- |+-- Module : Data.Array.Accelerate.CUDA.State+-- Copyright : [2008..2010] Manuel M T Chakravarty, Gabriele Keller, Sean Lee, Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Manuel M T Chakravarty <chak@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-partable (GHC extensions)+--+-- This module defines a state monad which keeps track of the code generator+-- state, including memory transfers and external compilation processes.+--++module Data.Array.Accelerate.CUDA.State+ (+ evalCUDA, runCUDA, CIO, unique, outputDir, deviceProps, memoryEntry, kernelEntry,+ KernelEntry(KernelEntry), kernelName, kernelStatus, Key,+ MemoryEntry(MemoryEntry), refcount, arena,++ freshVar,+ module Data.Record.Label+ )+ where++import Prelude hiding (id, (.), mod)+import Control.Category++import Data.Maybe+import Data.Binary+import Data.Record.Label+import Control.Arrow+import Control.Applicative+import Control.Exception+import Control.Monad.State (StateT(..), liftM)+import Data.Map (Map)+import Data.IntMap (IntMap)+import qualified Data.Map as M+import qualified Data.IntMap as IM++import System.Directory+import System.FilePath+import System.Posix.Process+import System.Posix.Types (ProcessID)++import Foreign.Ptr+import qualified Foreign.CUDA.Driver as CUDA+++-- The CUDA State Monad+-- ~~~~~~~~~~~~~~~~~~~~++-- Return the output directory for compilation by-products, creating if it does+-- not exist. This currently maps to a temporary directory, but could be mode to+-- point towards a persistent cache (eg: getAppUserDataDirectory)+--+getOutputDir :: IO FilePath+getOutputDir = do+ tmp <- getTemporaryDirectory+ pid <- getProcessID+ dir <- canonicalizePath $ tmp </> "ac" ++ show pid+ createDirectoryIfMissing True dir+ return dir++-- Store the kernel module map to file to the given directory+--+save :: FilePath -> Map Key KernelEntry -> IO ()+save f m = encodeFile f . map (second _kernelName) . filter compiled $ M.toAscList m+ where+ compiled (_,KernelEntry _ (Right _)) = True+ compiled _ = False++-- Read the kernel index map file (if it exists), loading modules into the+-- current context+--+load :: FilePath -> IO (Map Key KernelEntry)+load f = do+ x <- doesFileExist f+ if x then M.fromDistinctAscList <$> (mapM reload =<< decodeFile f)+ else return M.empty+ where+ reload (k,n) =+ (k,) . KernelEntry n . Right <$> CUDA.loadFile (n `replaceExtension` ".cubin")++-- |+-- Evaluate a CUDA array computation under a newly initialised environment,+-- discarding the final state.+--+evalCUDA :: CIO a -> IO a+evalCUDA = liftM fst . runCUDA++runCUDA :: CIO a -> IO (a, CUDAState)+runCUDA acc =+ bracket (initialise Nothing) finalise $ \(dev,_ctx) -> do+ props <- CUDA.props dev+ dir <- getOutputDir+ dict <- load (dir </> ".dict")+ (a,s) <- runStateT acc (CUDAState (M.size dict) dir props IM.empty dict)+ --+ -- TLM 2010-06-05: assert all memory has been released ??+ -- does CUDA.destroy release memory ??+ save (dir </> ".dict") (_kernelEntry s)+ return (a,s)++ where+ finalise = CUDA.destroy . snd+ initialise n = do+ CUDA.initialise []+ dev <- CUDA.device (fromMaybe 0 n) -- TLM: select the "best" device ??+ ctx <- CUDA.create dev [CUDA.SchedAuto]+ return (dev, ctx)+++-- | The state token for accelerated CUDA array operations+--+type CIO = StateT CUDAState IO+data CUDAState = CUDAState+ {+ _unique :: Int,+ _outputDir :: FilePath,+ _deviceProps :: CUDA.DeviceProperties,+ _memoryEntry :: IntMap MemoryEntry,+ _kernelEntry :: Map Key KernelEntry+ }++-- |+-- Associate an array expression with an external compilation tool (nvcc) or the+-- loaded function module+--+type Key = String+data KernelEntry = KernelEntry+ {+ _kernelName :: String,+ _kernelStatus :: Either ProcessID CUDA.Module+ }+++-- |+-- Reference tracking for device memory allocations. Associates the products of+-- an `Array dim e' with data stored on the graphics device. Facilitates reuse+-- and delayed allocation at the cost of explicit release.+--+-- This maps to a single concrete array. Arrays of pairs, for example, which are+-- represented internally as pairs of arrays, will generate two entries.+--+data MemoryEntry = MemoryEntry+ {+ _refcount :: Int,+ _arena :: WordPtr+ }++$(mkLabels [''CUDAState, ''MemoryEntry, ''KernelEntry])+++-- The derived labels (documentation goes here)+--+unique :: CUDAState :-> Int+outputDir :: CUDAState :-> FilePath+deviceProps :: CUDAState :-> CUDA.DeviceProperties+memoryEntry :: CUDAState :-> IntMap MemoryEntry+kernelEntry :: CUDAState :-> Map Key KernelEntry++refcount :: MemoryEntry :-> Int+arena :: MemoryEntry :-> WordPtr++kernelName :: KernelEntry :-> String+kernelStatus :: KernelEntry :-> Either ProcessID CUDA.Module+++-- | A unique name supply+--+freshVar :: CIO Int+freshVar = getM unique <* modM unique (+1)+
Data/Array/Accelerate/Interpreter.hs view
@@ -1,3 +1,4 @@+{-# OPTIONS_HADDOCK prune #-} {-# LANGUAGE GADTs, BangPatterns, PatternGuards #-} {-# LANGUAGE TypeFamilies, ScopedTypeVariables, FlexibleContexts #-} -- |@@ -16,8 +17,11 @@ module Data.Array.Accelerate.Interpreter ( -- * Interpret an array expression- Arrays, run- + Arrays, run,++ -- Internal+ evalPrim, evalPrimConst, evalPrj+ ) where -- standard libraries@@ -55,24 +59,6 @@ run = force . evalAcc . Sugar.convertAcc --- Environments--- ---------------- Valuation for an environment----data Val env where- Empty :: Val ()- Push :: Val env -> t -> Val (env, t)---- Projection of a value from a valuation using a de Bruijn index----prj :: Idx env t -> Val env -> t-prj ZeroIdx (Push _ v) = v-prj (SuccIdx idx) (Push val _) = prj idx val-prj _ _ = - error "Data.Array.Accelerate.Interpreter: prj: inconsistent valuation"-- -- Array expression evaluation -- --------------------------- @@ -115,9 +101,12 @@ = foldSegOp (evalFun f aenv) (evalExp e aenv) (evalOpenAcc acc1 aenv) (evalOpenAcc acc2 aenv) -evalOpenAcc (Scan f e acc) aenv- = scanOp (evalFun f aenv) (evalExp e aenv) (evalOpenAcc acc aenv)+evalOpenAcc (Scanl f e acc) aenv+ = scanlOp (evalFun f aenv) (evalExp e aenv) (evalOpenAcc acc aenv) +evalOpenAcc (Scanr f e acc) aenv+ = scanrOp (evalFun f aenv) (evalExp e aenv) (evalOpenAcc acc aenv)+ evalOpenAcc (Permute f dftAcc p acc) aenv = permuteOp (evalFun f aenv) (evalOpenAcc dftAcc aenv) (evalFun p aenv) (evalOpenAcc acc aenv)@@ -235,7 +224,7 @@ foldSegOp f e (DelayedArray _sh rf) seg@(DelayedArray shSeg rfSeg) = delay arr where- DelayedPair (DelayedArray _shSeg rfStarts) _ = scanOp (+) 0 seg+ DelayedPair (DelayedArray _shSeg rfStarts) _ = scanlOp (+) 0 seg arr = Sugar.newArray (Sugar.toElem shSeg) foldOne -- foldOne :: Sugar.DIM1 -> e@@ -249,12 +238,12 @@ fold v j end | j >= end = v | otherwise = fold (f v ((Sugar.liftToElem rf) j)) (j + 1) end- -scanOp :: (e -> e -> e)- -> e- -> Delayed (Vector e)- -> Delayed (Vector e, Scalar e)-scanOp f e (DelayedArray sh rf)++scanlOp :: (e -> e -> e)+ -> e+ -> Delayed (Vector e)+ -> Delayed (Vector e, Scalar e)+scanlOp f e (DelayedArray sh rf) = DelayedPair (delay $ adata `seq` Array sh adata) (unitOp (Sugar.toElem final)) where@@ -262,7 +251,7 @@ f' = Sugar.sinkFromElem2 f -- (adata, final) = runArrayData $ do- arr <- newArrayData n+ arr <- newArrayData n final <- traverse arr 0 (Sugar.fromElem e) return (arr, final) traverse arr i v@@ -270,7 +259,28 @@ | otherwise = do writeArrayData arr i v traverse arr (i + 1) (f' v (rf ((), i)))- ++scanrOp :: (e -> e -> e)+ -> e+ -> Delayed (Vector e)+ -> Delayed (Vector e, Scalar e)+scanrOp f e (DelayedArray sh rf)+ = DelayedPair (delay $ adata `seq` Array sh adata)+ (unitOp (Sugar.toElem final))+ where+ n = size sh+ f' = Sugar.sinkFromElem2 f+ --+ (adata, final) = runArrayData $ do+ arr <- newArrayData n+ final <- traverse arr (n-1) (Sugar.fromElem e)+ return (arr, final)+ traverse arr i v+ | i < 0 = return v+ | otherwise = do+ writeArrayData arr i v+ traverse arr (i - 1) (f' v (rf ((), i)))+ permuteOp :: (e -> e -> e) -> Delayed (Array dim' e) -> (dim -> dim')@@ -387,39 +397,57 @@ evalPrimConst (PrimPi ty) = evalPi ty evalPrim :: PrimFun p -> p-evalPrim (PrimAdd ty) = evalAdd ty-evalPrim (PrimSub ty) = evalSub ty-evalPrim (PrimMul ty) = evalMul ty-evalPrim (PrimNeg ty) = evalNeg ty-evalPrim (PrimAbs ty) = evalAbs ty-evalPrim (PrimSig ty) = evalSig ty-evalPrim (PrimQuot ty) = evalQuot ty-evalPrim (PrimRem ty) = evalRem ty-evalPrim (PrimIDiv ty) = evalIDiv ty-evalPrim (PrimMod ty) = evalMod ty-evalPrim (PrimBAnd ty) = evalBAnd ty-evalPrim (PrimBOr ty) = evalBOr ty-evalPrim (PrimBXor ty) = evalBXor ty-evalPrim (PrimBNot ty) = evalBNot ty-evalPrim (PrimFDiv ty) = evalFDiv ty-evalPrim (PrimRecip ty) = evalRecip ty-evalPrim (PrimLt ty) = evalLt ty-evalPrim (PrimGt ty) = evalGt ty-evalPrim (PrimLtEq ty) = evalLtEq ty-evalPrim (PrimGtEq ty) = evalGtEq ty-evalPrim (PrimEq ty) = evalEq ty-evalPrim (PrimNEq ty) = evalNEq ty-evalPrim (PrimMax ty) = evalMax ty-evalPrim (PrimMin ty) = evalMin ty-evalPrim PrimLAnd = evalLAnd-evalPrim PrimLOr = evalLOr-evalPrim PrimLNot = evalLNot-evalPrim PrimOrd = evalOrd-evalPrim PrimChr = evalChr-evalPrim PrimRoundFloatInt = evalRoundFloatInt-evalPrim PrimTruncFloatInt = evalTruncFloatInt-evalPrim PrimIntFloat = evalIntFloat-evalPrim PrimBoolToInt = evalBoolToInt+evalPrim (PrimAdd ty) = evalAdd ty+evalPrim (PrimSub ty) = evalSub ty+evalPrim (PrimMul ty) = evalMul ty+evalPrim (PrimNeg ty) = evalNeg ty+evalPrim (PrimAbs ty) = evalAbs ty+evalPrim (PrimSig ty) = evalSig ty+evalPrim (PrimQuot ty) = evalQuot ty+evalPrim (PrimRem ty) = evalRem ty+evalPrim (PrimIDiv ty) = evalIDiv ty+evalPrim (PrimMod ty) = evalMod ty+evalPrim (PrimBAnd ty) = evalBAnd ty+evalPrim (PrimBOr ty) = evalBOr ty+evalPrim (PrimBXor ty) = evalBXor ty+evalPrim (PrimBNot ty) = evalBNot ty+evalPrim (PrimBShiftL ty) = evalBShiftL ty+evalPrim (PrimBShiftR ty) = evalBShiftR ty+evalPrim (PrimBRotateL ty) = evalBRotateL ty+evalPrim (PrimBRotateR ty) = evalBRotateR ty+evalPrim (PrimFDiv ty) = evalFDiv ty+evalPrim (PrimRecip ty) = evalRecip ty+evalPrim (PrimSin ty) = evalSin ty+evalPrim (PrimCos ty) = evalCos ty+evalPrim (PrimTan ty) = evalTan ty+evalPrim (PrimAsin ty) = evalAsin ty+evalPrim (PrimAcos ty) = evalAcos ty+evalPrim (PrimAtan ty) = evalAtan ty+evalPrim (PrimAsinh ty) = evalAsinh ty+evalPrim (PrimAcosh ty) = evalAcosh ty+evalPrim (PrimAtanh ty) = evalAtanh ty+evalPrim (PrimExpFloating ty) = evalExpFloating ty+evalPrim (PrimSqrt ty) = evalSqrt ty+evalPrim (PrimLog ty) = evalLog ty+evalPrim (PrimFPow ty) = evalFPow ty+evalPrim (PrimLogBase ty) = evalLogBase ty+evalPrim (PrimLt ty) = evalLt ty+evalPrim (PrimGt ty) = evalGt ty+evalPrim (PrimLtEq ty) = evalLtEq ty+evalPrim (PrimGtEq ty) = evalGtEq ty+evalPrim (PrimEq ty) = evalEq ty+evalPrim (PrimNEq ty) = evalNEq ty+evalPrim (PrimMax ty) = evalMax ty+evalPrim (PrimMin ty) = evalMin ty+evalPrim PrimLAnd = evalLAnd+evalPrim PrimLOr = evalLOr+evalPrim PrimLNot = evalLNot+evalPrim PrimOrd = evalOrd+evalPrim PrimChr = evalChr+evalPrim PrimRoundFloatInt = evalRoundFloatInt+evalPrim PrimTruncFloatInt = evalTruncFloatInt+evalPrim PrimIntFloat = evalIntFloat+evalPrim PrimBoolToInt = evalBoolToInt -- Tuple construction and projection@@ -493,6 +521,49 @@ evalPi :: FloatingType a -> a evalPi ty | FloatingDict <- floatingDict ty = pi +evalSin :: FloatingType a -> (a -> a)+evalSin ty | FloatingDict <- floatingDict ty = sin++evalCos :: FloatingType a -> (a -> a)+evalCos ty | FloatingDict <- floatingDict ty = cos++evalTan :: FloatingType a -> (a -> a)+evalTan ty | FloatingDict <- floatingDict ty = tan++evalAsin :: FloatingType a -> (a -> a)+evalAsin ty | FloatingDict <- floatingDict ty = asin++evalAcos :: FloatingType a -> (a -> a)+evalAcos ty | FloatingDict <- floatingDict ty = acos++evalAtan :: FloatingType a -> (a -> a)+evalAtan ty | FloatingDict <- floatingDict ty = atan++evalAsinh :: FloatingType a -> (a -> a)+evalAsinh ty | FloatingDict <- floatingDict ty = asinh++evalAcosh :: FloatingType a -> (a -> a)+evalAcosh ty | FloatingDict <- floatingDict ty = acosh++evalAtanh :: FloatingType a -> (a -> a)+evalAtanh ty | FloatingDict <- floatingDict ty = atanh++evalExpFloating :: FloatingType a -> (a -> a)+evalExpFloating ty | FloatingDict <- floatingDict ty = exp++evalSqrt :: FloatingType a -> (a -> a)+evalSqrt ty | FloatingDict <- floatingDict ty = sqrt++evalLog :: FloatingType a -> (a -> a)+evalLog ty | FloatingDict <- floatingDict ty = log++evalFPow :: FloatingType a -> ((a, a) -> a)+evalFPow ty | FloatingDict <- floatingDict ty = uncurry (**)++evalLogBase :: FloatingType a -> ((a, a) -> a)+evalLogBase ty | FloatingDict <- floatingDict ty = uncurry logBase++ -- Methods of Num -- @@ -544,11 +615,25 @@ evalBNot :: IntegralType a -> (a -> a) evalBNot ty | IntegralDict <- integralDict ty = complement +evalBShiftL :: IntegralType a -> ((a, Int) -> a)+evalBShiftL ty | IntegralDict <- integralDict ty = uncurry shiftL++evalBShiftR :: IntegralType a -> ((a, Int) -> a)+evalBShiftR ty | IntegralDict <- integralDict ty = uncurry shiftR++evalBRotateL :: IntegralType a -> ((a, Int) -> a)+evalBRotateL ty | IntegralDict <- integralDict ty = uncurry rotateL++evalBRotateR :: IntegralType a -> ((a, Int) -> a)+evalBRotateR ty | IntegralDict <- integralDict ty = uncurry rotateR+ evalFDiv :: FloatingType a -> ((a, a) -> a) evalFDiv ty | FloatingDict <- floatingDict ty = uncurry (/) evalRecip :: FloatingType a -> (a -> a) evalRecip ty | FloatingDict <- floatingDict ty = recip++ evalLt :: ScalarType a -> ((a, a) -> Bool) evalLt (NumScalarType (IntegralNumType ty))
Data/Array/Accelerate/Language.hs view
@@ -32,11 +32,11 @@ reshape, -- ** Collective array operations- slice, replicate, zip, unzip, map, zipWith, scan, fold, foldSeg, permute,- backpermute,+ slice, replicate, zip, unzip, map, zipWith, scanl, scanr, fold, foldSeg,+ permute, backpermute, -- ** Tuple construction and destruction- Tuple(..),+ Tuple(..), fst, snd, curry, uncurry, -- ** Conditional expressions (?),@@ -44,16 +44,18 @@ -- ** Array operations with a scalar result (!), shape, - -- ** Methods of H98 classes that we need to redefine as their signatures- -- change + -- ** Methods of H98 classes that we need to redefine as their signatures change (==*), (/=*), (<*), (<=*), (>*), (>=*), max, min,+ bit, setBit, clearBit, complementBit, testBit,+ shift, shiftL, shiftR,+ rotate, rotateL, rotateR, -- ** Standard functions that we need to redefine as their signatures change (&&*), (||*), not, -- ** Conversions- boolToInt,- + boolToInt, intToFloat, roundFloatToInt, truncateFloatToInt,+ -- ** Constants ignore @@ -63,12 +65,11 @@ ) where -- avoid clashes with Prelude functions-import Prelude hiding (replicate, zip, unzip, map, zipWith, filter, max, min,- not, const)-import qualified Prelude+import Prelude hiding (replicate, zip, unzip, map, scanl, scanr, zipWith,+ filter, max, min, not, const, fst, snd, curry, uncurry) -- standard libraries-import Data.Bits+import Data.Bits (Bits((.&.), (.|.), xor, complement)) -- friends import Data.Array.Accelerate.Type@@ -140,17 +141,11 @@ -- |The converse of 'zip', but the shape of the two results is identical to the -- shape of the argument. -- -unzip :: forall a b dim. (Ix dim, Elem a, Elem b) +unzip :: (Ix dim, Elem a, Elem b) => Acc (Array dim (a, b)) -> (Acc (Array dim a), Acc (Array dim b)) unzip arr = (map fst arr, map snd arr)- where- fst :: Exp (a, b) -> Exp a- fst e = let (x, _:: Exp b) = untuple e in x - snd :: Exp (a, b) -> Exp b- snd e = let (_ :: Exp a, y) = untuple e in y- -- |Apply the given function elementwise to the given array. -- map :: (Ix dim, Elem a, Elem b) @@ -168,20 +163,29 @@ -> Acc (Array dim c) zipWith = ZipWith --- |Prescan of a vector. The type 'a' together with the binary function (first--- argument) and value (second argument) must form a monoid; i.e., the +-- |Prescan of a vector. The type \'a\' together with the binary function+-- (first argument) and value (second argument) must form a monoid; i.e., the -- function must be /associative/ and the value must be its /neutral element/. -- -- The resulting vector of prescan values has the same size as the argument -- vector. The resulting scalar is the reduction value.--- -scan :: Elem a- => (Exp a -> Exp a -> Exp a) - -> Exp a - -> Acc (Vector a)- -> (Acc (Vector a), Acc (Scalar a))-scan f e arr = unpair (Scan f e arr)+--+scanl :: Elem a+ => (Exp a -> Exp a -> Exp a)+ -> Exp a+ -> Acc (Vector a)+ -> (Acc (Vector a), Acc (Scalar a))+scanl f e arr = unpair (Scanl f e arr) +-- |The right-to-left dual of 'scanl'.+--+scanr :: Elem a+ => (Exp a -> Exp a -> Exp a)+ -> Exp a+ -> Acc (Vector a)+ -> (Acc (Vector a), Acc (Scalar a))+scanr f e arr = unpair (Scanr f e arr)+ -- |Reduction of an array. The type 'a' together with the binary function -- (first argument) and value (second argument) must form a monoid; i.e., the -- function must be /associative/ and the value must be its /neutral element/.@@ -266,6 +270,26 @@ untuple = untup5 +-- |Extract the first component of a pair+--+fst :: forall a b. (Elem a, Elem b) => Exp (a, b) -> Exp a+fst e = let (x, _:: Exp b) = untuple e in x++-- |Extract the second component of a pair+snd :: forall a b. (Elem a, Elem b) => Exp (a, b) -> Exp b+snd e = let (_ :: Exp a, y) = untuple e in y++-- |Converts an uncurried function to a curried function+--+curry :: (Elem a, Elem b) => (Exp (a,b) -> Exp c) -> Exp a -> Exp b -> Exp c+curry f x y = f (tuple (x,y))++-- |Converts a curried function to a function on pairs+--+uncurry :: (Elem a, Elem b) => (Exp a -> Exp b -> Exp c) -> Exp (a,b) -> Exp c+uncurry f t = let (x,y) = untuple t in f x y++ -- Conditional expressions -- ----------------------- @@ -285,7 +309,7 @@ (!) :: (Ix dim, Elem e) => Acc (Array dim e) -> Exp dim -> Exp e (!) = IndexScalar -shape :: Ix dim => Acc (Array dim e) -> Exp dim+shape :: (Ix dim, Elem dim) => Acc (Array dim e) -> Exp dim shape = Shape @@ -301,11 +325,13 @@ -- pred = mkPred -- FIXME: ops -instance (Elem t, IsScalar t) => Prelude.Eq (Exp t)+instance (Elem t, IsScalar t) => Prelude.Eq (Exp t) where -- FIXME: instance makes no sense with standard signatures+ (==) = error "Prelude.Eq.== applied to EDSL types" -instance (Elem t, IsScalar t) => Prelude.Ord (Exp t)+instance (Elem t, IsScalar t) => Prelude.Ord (Exp t) where -- FIXME: instance makes no sense with standard signatures+ compare = error "Prelude.Ord.compare applied to EDSL types" instance (Elem t, IsNum t, IsIntegral t) => Bits (Exp t) where (.&.) = mkBAnd@@ -314,6 +340,28 @@ complement = mkBNot -- FIXME: argh, the rest have fixed types in their signatures +shift, shiftL, shiftR :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp t+shift x i = i ==* 0 ? (x, i <* 0 ? (x `shiftR` (-i), x `shiftL` i))+shiftL = mkBShiftL+shiftR = mkBShiftR++rotate, rotateL, rotateR :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp t+rotate x i = i ==* 0 ? (x, i <* 0 ? (x `rotateR` (-i), x `rotateL` i))+rotateL = mkBRotateL+rotateR = mkBRotateR++bit :: (Elem t, IsIntegral t) => Exp Int -> Exp t+bit x = 1 `shiftL` x++setBit, clearBit, complementBit :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp t+x `setBit` i = x .|. bit i+x `clearBit` i = x .&. complement (bit i)+x `complementBit` i = x `xor` bit i++testBit :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp Bool+x `testBit` i = (x .&. bit i) /=* 0++ instance (Elem t, IsNum t) => Num (Exp t) where (+) = mkAdd (-) = mkSub@@ -338,12 +386,26 @@ instance (Elem t, IsFloating t) => Floating (Exp t) where pi = mkPi+ sin = mkSin+ cos = mkCos+ tan = mkTan+ asin = mkAsin+ acos = mkAcos+ atan = mkAtan+ asinh = mkAsinh+ acosh = mkAcosh+ atanh = mkAtanh+ exp = mkExpFloating+ sqrt = mkSqrt+ log = mkLog+ (**) = mkFPow+ logBase = mkLogBase -- FIXME: add other ops instance (Elem t, IsFloating t) => Fractional (Exp t) where (/) = mkFDiv recip = mkRecip- fromRational = exp . fromRational+ fromRational = constant . fromRational -- FIXME: add other ops instance (Elem t, IsFloating t) => RealFrac (Exp t)@@ -431,6 +493,18 @@ -- boolToInt :: Exp Bool -> Exp Int boolToInt = mkBoolToInt++-- |Convert an Int to a Float+intToFloat :: Exp Int -> Exp Float+intToFloat = mkIntFloat++-- |Round Float to Int+roundFloatToInt :: Exp Float -> Exp Int+roundFloatToInt = mkRoundFloatInt++-- |Truncate Float to Int+truncateFloatToInt :: Exp Float -> Exp Int+truncateFloatToInt = mkTruncFloatInt -- Constants
Data/Array/Accelerate/Pretty.hs view
@@ -20,7 +20,6 @@ import Text.PrettyPrint -- friends-import Data.Array.Accelerate.Type import Data.Array.Accelerate.Array.Sugar import Data.Array.Accelerate.Tuple import Data.Array.Accelerate.AST@@ -73,9 +72,12 @@ prettyAcc lvl (FoldSeg f e acc1 acc2) = prettyArrOp "foldSeg" [parens (prettyFun lvl f), prettyExp lvl parens e, prettyAccParens lvl acc1, prettyAccParens lvl acc2]-prettyAcc lvl (Scan f e acc) - = prettyArrOp "scan" [parens (prettyFun lvl f), prettyExp lvl parens e,+prettyAcc lvl (Scanl f e acc)+ = prettyArrOp "scanl" [parens (prettyFun lvl f), prettyExp lvl parens e, prettyAccParens lvl acc]+prettyAcc lvl (Scanr f e acc)+ = prettyArrOp "scanr" [parens (prettyFun lvl f), prettyExp lvl parens e,+ prettyAccParens lvl acc] prettyAcc lvl (Permute f dfts p acc) = prettyArrOp "permute" [parens (prettyFun lvl f), prettyAccParens lvl dfts, parens (prettyFun lvl p), prettyAccParens lvl acc]@@ -99,8 +101,8 @@ prettyFun lvl fun = let (n, bodyDoc) = count fun in- char '\\' <> hsep [text $ "x" ++ show idx | idx <- [0..n]] <+> text "->" <+> - bodyDoc+ char '\\' <> hsep [text $ "x" ++ show idx | idx <- reverse [0..n]] <+> + text "->" <+> bodyDoc where count :: OpenFun env aenv fun -> (Int, Doc) count (Body body) = (-1, prettyExp lvl noParens body)@@ -159,39 +161,57 @@ -- Pretty print a primitive operation -- prettyPrim :: PrimFun a -> Doc-prettyPrim (PrimAdd _) = text "(+)"-prettyPrim (PrimSub _) = text "(-)"-prettyPrim (PrimMul _) = text "(*)"-prettyPrim (PrimNeg _) = text "negate"-prettyPrim (PrimAbs _) = text "abs"-prettyPrim (PrimSig _) = text "signum"-prettyPrim (PrimQuot _) = text "quot"-prettyPrim (PrimRem _) = text "rem"-prettyPrim (PrimIDiv _) = text "div"-prettyPrim (PrimMod _) = text "mod"-prettyPrim (PrimBAnd _) = text "(.&.)"-prettyPrim (PrimBOr _) = text "(.|.)"-prettyPrim (PrimBXor _) = text "xor"-prettyPrim (PrimBNot _) = text "complement"-prettyPrim (PrimFDiv _) = text "(/)"-prettyPrim (PrimRecip _) = text "recip"-prettyPrim (PrimLt _) = text "(<*)"-prettyPrim (PrimGt _) = text "(>*)"-prettyPrim (PrimLtEq _) = text "(<=*)"-prettyPrim (PrimGtEq _) = text "(>=*)"-prettyPrim (PrimEq _) = text "(==*)"-prettyPrim (PrimNEq _) = text "(/=*)"-prettyPrim (PrimMax _) = text "max"-prettyPrim (PrimMin _) = text "min"-prettyPrim PrimLAnd = text "&&*"-prettyPrim PrimLOr = text "||*"-prettyPrim PrimLNot = text "not"-prettyPrim PrimOrd = text "ord"-prettyPrim PrimChr = text "chr"-prettyPrim PrimRoundFloatInt = text "round"-prettyPrim PrimTruncFloatInt = text "trunc"-prettyPrim PrimIntFloat = text "intFloat"-prettyPrim PrimBoolToInt = text "boolToInt"+prettyPrim (PrimAdd _) = text "(+)"+prettyPrim (PrimSub _) = text "(-)"+prettyPrim (PrimMul _) = text "(*)"+prettyPrim (PrimNeg _) = text "negate"+prettyPrim (PrimAbs _) = text "abs"+prettyPrim (PrimSig _) = text "signum"+prettyPrim (PrimQuot _) = text "quot"+prettyPrim (PrimRem _) = text "rem"+prettyPrim (PrimIDiv _) = text "div"+prettyPrim (PrimMod _) = text "mod"+prettyPrim (PrimBAnd _) = text "(.&.)"+prettyPrim (PrimBOr _) = text "(.|.)"+prettyPrim (PrimBXor _) = text "xor"+prettyPrim (PrimBNot _) = text "complement"+prettyPrim (PrimBShiftL _) = text "shiftL"+prettyPrim (PrimBShiftR _) = text "shiftR"+prettyPrim (PrimBRotateL _) = text "rotateL"+prettyPrim (PrimBRotateR _) = text "rotateR"+prettyPrim (PrimFDiv _) = text "(/)"+prettyPrim (PrimRecip _) = text "recip"+prettyPrim (PrimSin _) = text "sin"+prettyPrim (PrimCos _) = text "cos"+prettyPrim (PrimTan _) = text "tan"+prettyPrim (PrimAsin _) = text "asin"+prettyPrim (PrimAcos _) = text "acos"+prettyPrim (PrimAtan _) = text "atan"+prettyPrim (PrimAsinh _) = text "asinh"+prettyPrim (PrimAcosh _) = text "acosh"+prettyPrim (PrimAtanh _) = text "atanh"+prettyPrim (PrimExpFloating _) = text "exp"+prettyPrim (PrimSqrt _) = text "sqrt"+prettyPrim (PrimLog _) = text "log"+prettyPrim (PrimFPow _) = text "(**)"+prettyPrim (PrimLogBase _) = text "logBase"+prettyPrim (PrimLt _) = text "(<*)"+prettyPrim (PrimGt _) = text "(>*)"+prettyPrim (PrimLtEq _) = text "(<=*)"+prettyPrim (PrimGtEq _) = text "(>=*)"+prettyPrim (PrimEq _) = text "(==*)"+prettyPrim (PrimNEq _) = text "(/=*)"+prettyPrim (PrimMax _) = text "max"+prettyPrim (PrimMin _) = text "min"+prettyPrim PrimLAnd = text "&&*"+prettyPrim PrimLOr = text "||*"+prettyPrim PrimLNot = text "not"+prettyPrim PrimOrd = text "ord"+prettyPrim PrimChr = text "chr"+prettyPrim PrimRoundFloatInt = text "round"+prettyPrim PrimTruncFloatInt = text "trunc"+prettyPrim PrimIntFloat = text "intFloat"+prettyPrim PrimBoolToInt = text "boolToInt" {- -- Pretty print type
Data/Array/Accelerate/Smart.hs view
@@ -31,12 +31,19 @@ tup2, tup3, tup4, tup5, untup2, untup3, untup4, untup5, -- * Smart constructors for constants- mkMinBound, mkMaxBound, mkPi,+ mkMinBound, mkMaxBound, mkPi, + mkSin, mkCos, mkTan,+ mkAsin, mkAcos, mkAtan,+ mkAsinh, mkAcosh, mkAtanh,+ mkExpFloating, mkSqrt, mkLog,+ mkFPow, mkLogBase, -- * Smart constructors for primitive functions mkAdd, mkSub, mkMul, mkNeg, mkAbs, mkSig, mkQuot, mkRem, mkIDiv, mkMod,- mkBAnd, mkBOr, mkBXor, mkBNot, mkFDiv, mkRecip, mkLt, mkGt, mkLtEq, mkGtEq,- mkEq, mkNEq, mkMax, mkMin, mkLAnd, mkLOr, mkLNot, mkBoolToInt+ mkBAnd, mkBOr, mkBXor, mkBNot, mkBShiftL, mkBShiftR, mkBRotateL, mkBRotateR,+ mkFDiv, mkRecip, mkLt, mkGt, mkLtEq, mkGtEq,+ mkEq, mkNEq, mkMax, mkMin, mkLAnd, mkLOr, mkLNot, mkBoolToInt, mkIntFloat,+ mkRoundFloatInt, mkTruncFloatInt ) where @@ -61,9 +68,11 @@ -- data Acc a where - FstArray :: Acc (Array dim1 e1, Array dim2 e2)+ FstArray :: (Elem e1, Elem e2)+ => Acc (Array dim1 e1, Array dim2 e2) -> Acc (Array dim1 e1)- SndArray :: Acc (Array dim1 e1, Array dim2 e2)+ SndArray :: (Elem e1, Elem e2)+ => Acc (Array dim1 e1, Array dim2 e2) -> Acc (Array dim2 e2) Use :: Array dim e -> Acc (Array dim e)@@ -102,11 +111,16 @@ -> Acc (Vector e) -> Acc Segments -> Acc (Vector e)- Scan :: Elem e+ Scanl :: Elem e => (Exp e -> Exp e -> Exp e) -> Exp e -> Acc (Vector e) -> Acc (Vector e, Scalar e)+ Scanr :: Elem e+ => (Exp e -> Exp e -> Exp e)+ -> Exp e+ -> Acc (Vector e)+ -> Acc (Vector e, Scalar e) Permute :: (Ix dim, Ix dim', Elem e) => (Exp e -> Exp e -> Exp e) -> Acc (Array dim' e)@@ -151,8 +165,10 @@ convertOpenAcc alyt (FoldSeg f e acc1 acc2) = AST.FoldSeg (convertFun2 alyt f) (convertExp alyt e) (convertOpenAcc alyt acc1) (convertOpenAcc alyt acc2)-convertOpenAcc alyt (Scan f e acc) - = AST.Scan (convertFun2 alyt f) (convertExp alyt e) (convertOpenAcc alyt acc)+convertOpenAcc alyt (Scanl f e acc)+ = AST.Scanl (convertFun2 alyt f) (convertExp alyt e) (convertOpenAcc alyt acc)+convertOpenAcc alyt (Scanr f e acc)+ = AST.Scanr (convertFun2 alyt f) (convertExp alyt e) (convertOpenAcc alyt acc) convertOpenAcc alyt (Permute f dftAcc perm acc) = AST.Permute (convertFun2 alyt f) (convertOpenAcc alyt dftAcc)@@ -202,7 +218,8 @@ PrimApp :: (Elem a, Elem r) => PrimFun (a -> r) -> Exp a -> Exp r IndexScalar :: Acc (Array dim t) -> Exp dim -> Exp t- Shape :: Acc (Array dim e) -> Exp dim+ Shape :: Elem dim+ => Acc (Array dim e) -> Exp dim -- |Conversion from HOAS to de Bruijn expression AST@@ -407,6 +424,48 @@ mkPi :: (Elem r, IsFloating r) => Exp r mkPi = PrimConst (PrimPi floatingType) +mkSin :: (Elem t, IsFloating t) => Exp t -> Exp t+mkSin x = PrimSin floatingType `PrimApp` x++mkCos :: (Elem t, IsFloating t) => Exp t -> Exp t+mkCos x = PrimCos floatingType `PrimApp` x++mkTan :: (Elem t, IsFloating t) => Exp t -> Exp t+mkTan x = PrimTan floatingType `PrimApp` x++mkAsin :: (Elem t, IsFloating t) => Exp t -> Exp t+mkAsin x = PrimAsin floatingType `PrimApp` x++mkAcos :: (Elem t, IsFloating t) => Exp t -> Exp t+mkAcos x = PrimAcos floatingType `PrimApp` x++mkAtan :: (Elem t, IsFloating t) => Exp t -> Exp t+mkAtan x = PrimAtan floatingType `PrimApp` x++mkAsinh :: (Elem t, IsFloating t) => Exp t -> Exp t+mkAsinh x = PrimAsinh floatingType `PrimApp` x++mkAcosh :: (Elem t, IsFloating t) => Exp t -> Exp t+mkAcosh x = PrimAcosh floatingType `PrimApp` x++mkAtanh :: (Elem t, IsFloating t) => Exp t -> Exp t+mkAtanh x = PrimAtanh floatingType `PrimApp` x++mkExpFloating :: (Elem t, IsFloating t) => Exp t -> Exp t+mkExpFloating x = PrimExpFloating floatingType `PrimApp` x++mkSqrt :: (Elem t, IsFloating t) => Exp t -> Exp t+mkSqrt x = PrimSqrt floatingType `PrimApp` x++mkLog :: (Elem t, IsFloating t) => Exp t -> Exp t+mkLog x = PrimLog floatingType `PrimApp` x++mkFPow :: (Elem t, IsFloating t) => Exp t -> Exp t -> Exp t+mkFPow x y = PrimFPow floatingType `PrimApp` tup2 (x, y)++mkLogBase :: (Elem t, IsFloating t) => Exp t -> Exp t -> Exp t+mkLogBase x y = PrimLogBase floatingType `PrimApp` tup2 (x, y)+ -- Smart constructors for primitive applications -- @@ -455,8 +514,19 @@ mkBNot :: (Elem t, IsIntegral t) => Exp t -> Exp t mkBNot x = PrimBNot integralType `PrimApp` x- -- FIXME: add shifts +mkBShiftL :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp t+mkBShiftL x i = PrimBShiftL integralType `PrimApp` tup2 (x, i)++mkBShiftR :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp t+mkBShiftR x i = PrimBShiftR integralType `PrimApp` tup2 (x, i)++mkBRotateL :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp t+mkBRotateL x i = PrimBRotateL integralType `PrimApp` tup2 (x, i)++mkBRotateR :: (Elem t, IsIntegral t) => Exp t -> Exp Int -> Exp t+mkBRotateR x i = PrimBRotateR integralType `PrimApp` tup2 (x, i)+ -- Operators from Fractional, Floating, RealFrac & RealFloat mkFDiv :: (Elem t, IsFloating t) => Exp t -> Exp t -> Exp t@@ -464,6 +534,7 @@ mkRecip :: (Elem t, IsFloating t) => Exp t -> Exp t mkRecip x = PrimRecip floatingType `PrimApp` x+ -- FIXME: add operations from Floating, RealFrac & RealFloat -- Relational and equality operators@@ -484,7 +555,7 @@ mkEq x y = PrimEq scalarType `PrimApp` tup2 (x, y) mkNEq :: (Elem t, IsScalar t) => Exp t -> Exp t -> Exp Bool-mkNEq x y = PrimLt scalarType `PrimApp` tup2 (x, y)+mkNEq x y = PrimNEq scalarType `PrimApp` tup2 (x, y) mkMax :: (Elem t, IsScalar t) => Exp t -> Exp t -> Exp t mkMax x y = PrimMax scalarType `PrimApp` tup2 (x, y)@@ -511,4 +582,13 @@ mkBoolToInt :: Exp Bool -> Exp Int mkBoolToInt b = PrimBoolToInt `PrimApp` b++mkIntFloat :: Exp Int -> Exp Float+mkIntFloat x = PrimIntFloat `PrimApp` x++mkRoundFloatInt :: Exp Float -> Exp Int+mkRoundFloatInt x = PrimRoundFloatInt `PrimApp` x++mkTruncFloatInt :: Exp Float -> Exp Int+mkTruncFloatInt x = PrimTruncFloatInt `PrimApp` x
Data/Array/Accelerate/Tuple.hs view
@@ -38,8 +38,8 @@ -- NB: We index tuples by starting to count from the *right*! -- data TupleIdx t e where- ZeroTupIdx :: TupleIdx (t, s) s- SuccTupIdx :: TupleIdx t e -> TupleIdx (t, s) e+ ZeroTupIdx :: Elem s => TupleIdx (t, s) s+ SuccTupIdx :: TupleIdx t e -> TupleIdx (t, s) e -- |Conversion between surface n-tuples and our tuple representation. --
Data/Array/Accelerate/Type.hs view
@@ -33,6 +33,7 @@ import Data.Int import Data.Typeable import Data.Word+import Foreign.Storable import Foreign.C.Types ( CChar, CSChar, CUChar, CShort, CUShort, CInt, CUInt, CLong, CULong, CLLong, CULLong, CFloat, CDouble)@@ -47,17 +48,18 @@ data IntegralDict a where IntegralDict :: ( Bounded a, Enum a, Eq a, Ord a, Show a- , Bits a, Integral a, Num a, Real a) + , Bits a, Integral a, Num a, Real a, Storable a) => IntegralDict a data FloatingDict a where FloatingDict :: ( Enum a, Eq a, Ord a, Show a , Floating a, Fractional a, Num a, Real a, RealFrac a- , RealFloat a)+ , RealFloat a, Storable a) => FloatingDict a data NonNumDict a where- NonNumDict :: (Bounded a, Enum a, Eq a, Ord a, Show a) => NonNumDict a+ NonNumDict :: (Bounded a, Enum a, Eq a, Ord a, Show a, Storable a)+ => NonNumDict a -- Scalar type representation -- @@ -532,6 +534,16 @@ nonNumDict (TypeCChar dict) = dict nonNumDict (TypeCSChar dict) = dict nonNumDict (TypeCUChar dict) = dict+++-- Tuple type+-- ----------++data TupleType a where+ UnitTuple :: TupleType ()+ SingleTuple :: ScalarType a -> TupleType a+ PairTuple :: TupleType a -> TupleType b -> TupleType (a, b)+ {- -- Vector GPU data types
INSTALL view
@@ -1,4 +1,7 @@-Requirements: Glasgow Haskell Compiler (GHC), 6.10.1 or later+Requirements: +- Glasgow Haskell Compiler (GHC), 6.12.1 or later+- Haskell libraries as specified in 'accelerate.cabal'+- For the CUDA backend, CUDA version 3.0 or later Standard Cabal installation: @@ -10,10 +13,13 @@ Then, to use the library, pass the flag "-package accelerate" to GHC. -WARNING: This is at best an *alpha* release. The library isn't actually useful- for anything at this stage, except for people interested in writing- a backend. The API is also guaranteed to going to change a few - more times before settling down. You have been warned.- +WARNING: This is an early beta release. Most features are implemented + in both the interpreter and CUDA backend. The code has been+ lightly tested. The Accelerate API will surely change a few+ more times before settling down. You have been warned.+ +Please report bugs at http://trac.haskell.org/accelerate+The project web page is at http://www.cse.unsw.edu.au/~chak/project/accelerate/+ Direct questions at Manuel M T Chakravarty <chak@cse.unsw.edu.au>-(aka ChilliX on #haskell and friends).+(aka TacticalGrace on #haskell and friends).
accelerate.cabal view
@@ -1,54 +1,144 @@-Name: accelerate-Version: 0.6.0.0-Cabal-version: >= 1.6-Tested-with: GHC >= 6.10.1+Name: accelerate+Version: 0.7.1.0+Cabal-version: >= 1.6+Tested-with: GHC >= 6.12.1+Build-type: Simple -Synopsis: An embedded language for accelerated array processing-Description: This library defines an embedded language for- regular, multi-dimensional array computations with- multiple backends to facilitate high-performance- implementations. Currently, the only backend is an- interpreter that serves as a reference implementation - of the intended semantics of the language.-License: BSD3-License-file: LICENSE-Author: Manuel M T Chakravarty, Gabriele Keller, Sean Lee-Maintainer: Manuel M T Chakravarty <chak@cse.unsw.edu.au>-Homepage: http://www.cse.unsw.edu.au/~chak/project/accelerate/+Synopsis: An embedded language for accelerated array processing+Description: This library defines an embedded language for+ regular, multi-dimensional array computations with+ multiple backends to facilitate high-performance+ implementations. Currently, there are two backends:+ (1) an interpreter that serves as a reference + implementation of the intended semantics of the+ language and (2) a CUDA backend generating code for+ CUDA-capable NVIDIA GPUs.+ .+ To use the CUDA backend, you need to have CUDA version 3.x+ installed. The CUDA backend still misses some features of+ the full language; in particular, the array operations+ 'replicate', 'slice', and 'foldSeg' are not yet supported.+ .+ Known bugs in this version: http://trac.haskell.org/accelerate/query?status=new&status=assigned&status=reopened&status=closed&version=0.7.1.0&order=priority+ .+ * New in 0.7.1.0: the CUDA backend and a number of scalar functions+License: BSD3+License-file: LICENSE+Author: Manuel M T Chakravarty, + Gabriele Keller, + Sean Lee, + Trevor L. McDonell+Maintainer: Manuel M T Chakravarty <chak@cse.unsw.edu.au>+Homepage: http://www.cse.unsw.edu.au/~chak/project/accelerate/+Bug-reports: http://trac.haskell.org/accelerate -Category: Compilers/Interpreters, Concurrency, Data-Stability: Experimental+Category: Compilers/Interpreters, Concurrency, Data+Stability: Experimental -Build-type: Simple-Build-depends: array, - base == 3.*, - ghc-prim, - haskell98, - pretty-Exposed-modules: Data.Array.Accelerate- Data.Array.Accelerate.Interpreter-Other-modules: Data.Array.Accelerate.Array.Data- Data.Array.Accelerate.Array.Delayed- Data.Array.Accelerate.Array.Representation- Data.Array.Accelerate.Array.Sugar- Data.Array.Accelerate.AST- Data.Array.Accelerate.Debug- Data.Array.Accelerate.Language- Data.Array.Accelerate.Pretty- Data.Array.Accelerate.Smart- Data.Array.Accelerate.Tuple- Data.Array.Accelerate.Type-Extra-source-files: INSTALL- examples/simple/DotP.hs- examples/simple/Filter.hs- examples/simple/Main.hs- examples/simple/Makefile- examples/simple/SAXPY.hs- examples/simple/SMVM.hs- examples/simple/Time.hs+-- Should be in the Library stanza, and only enabled for the CUDA backend,+-- but Cabal does not support that.+Data-dir: cubits+Data-files: accelerate_cuda_extras.h+ accelerate_cuda_utils.h+ backpermute.inl+ fold.inl+ map.inl+ permute.inl+ zipWith.inl+ thrust/scan_safe.inl -Ghc-options: -O2 -Wall -fno-warn-orphans -fno-warn-name-shadowing-Extensions: FlexibleContexts, FlexibleInstances, - ExistentialQuantification, GADTs, TypeFamilies, - ScopedTypeVariables, DeriveDataTypeable,- BangPatterns, PatternGuards, TypeOperators, RankNTypes+Extra-source-files: INSTALL+ examples/simple/DotP.hs+ examples/simple/Filter.hs+ examples/simple/Main.hs+ examples/simple/Makefile+ examples/simple/SAXPY.hs+ examples/simple/SMVM.hs+ examples/simple/Square.hs+ examples/simple/Sum.hs+ examples/simple/Time.hs+ examples/rasterize/RasterizeAcc.hs+ examples/rasterize/rasterize-test1.txt+ examples/rasterize/rasterize-test2.txt+ examples/rasterize/rasterize-test3.txt+ examples/rasterize/rasterize-test4.txt+ examples/rasterize/rasterize.hs++Flag llvm+ Description: enable the LLVM backend (sequential)+ Default: False++Flag cuda+ Description: enable the CUDA parallel backend for NVIDIA GPUs+ Default: True++Library+ Build-depends: array, + base == 4.*, + ghc-prim, + haskell98,+ pretty+ If flag(llvm)+ Build-depends: llvm >= 0.6.8++ if flag(cuda)+ Build-depends: binary,+ bytestring,+ containers,+ cuda >= 0.2 && < 0.3,+ directory,+ fclabels,+ filepath,+ language-c >= 0.3 && < 0.4,+ monads-fd,+ transformers >= 0.2 && < 0.3,+ unix++ Exposed-modules: Data.Array.Accelerate+ Data.Array.Accelerate.Interpreter+-- If flag(llvm)+-- Exposed-modules: Data.Array.Accelerate.LLVM++ If flag(cuda)+ Exposed-modules: Data.Array.Accelerate.CUDA+ + Other-modules: Data.Array.Accelerate.Array.Data+ Data.Array.Accelerate.Array.Delayed+ Data.Array.Accelerate.Array.Representation+ Data.Array.Accelerate.Array.Sugar+ Data.Array.Accelerate.Analysis.Type+ Data.Array.Accelerate.AST+ Data.Array.Accelerate.Debug+ Data.Array.Accelerate.Language+ Data.Array.Accelerate.Pretty+ Data.Array.Accelerate.Smart+ Data.Array.Accelerate.Tuple+ Data.Array.Accelerate.Type+ Paths_accelerate+-- If flag(llvm)+-- Other-modules: Data.Array.Accelerate.LLVM.CodeGen++ If flag(cuda)+ CPP-options: -DACCELERATE_CUDA_BACKEND+ Other-modules: Data.Array.Accelerate.CUDA.Analysis.Hash+ Data.Array.Accelerate.CUDA.Analysis.Launch+ Data.Array.Accelerate.CUDA.Array.Data+ Data.Array.Accelerate.CUDA.Array.Device+ Data.Array.Accelerate.CUDA.CodeGen.Data+ Data.Array.Accelerate.CUDA.CodeGen.Skeleton+ Data.Array.Accelerate.CUDA.CodeGen.Tuple+ Data.Array.Accelerate.CUDA.CodeGen.Util+ Data.Array.Accelerate.CUDA.CodeGen+ Data.Array.Accelerate.CUDA.Compile+ Data.Array.Accelerate.CUDA.Execute+ Data.Array.Accelerate.CUDA.State++ Ghc-options: -O2 -Wall -fno-warn-orphans -fno-warn-name-shadowing+ Extensions: FlexibleContexts, FlexibleInstances, + ExistentialQuantification, GADTs, TypeFamilies, + ScopedTypeVariables, DeriveDataTypeable,+ BangPatterns, PatternGuards, TypeOperators, RankNTypes++source-repository head+ type: darcs+ location: http://code.haskell.org/accelerate
+ cubits/accelerate_cuda_extras.h view
@@ -0,0 +1,207 @@+/* -----------------------------------------------------------------------------+ *+ * Module : Extras+ * Copyright : (c) [2009..2010] Trevor L. McDonell+ * License : BSD+ *+ * ---------------------------------------------------------------------------*/++#ifndef __ACCELERATE_CUDA_EXTRAS_H__+#define __ACCELERATE_CUDA_EXTRAS_H__++#include <stdio.h>+#include <stdint.h>++#include <cuda_runtime.h>++/* -----------------------------------------------------------------------------+ * Textures+ * -----------------------------------------------------------------------------+ *+ * CUDA texture definitions and access functions are defined in terms of+ * templates, and hence only available through the C++ interface. Expose some+ * dummy wrappers to enable parsing with language-c.+ *+ * We don't have a definition for `Int' or `Word', since the bitwidth of the+ * Haskell and C types may be different.+ *+ * NOTE ON 64-BIT TYPES+ * The CUDA device uses little-endian arithmetic. We haven't accounted for the+ * fact that this may be different on the host, for both initial data transfer+ * and the unpacking below.+ */+#if defined(__cplusplus) && defined(__CUDACC__)++typedef texture<uint2, 1> TexWord64;+typedef texture<uint32_t, 1> TexWord32;+typedef texture<uint16_t, 1> TexWord16;+typedef texture<uint8_t, 1> TexWord8;+typedef texture<int2, 1> TexInt64;+typedef texture<int32_t, 1> TexInt32;+typedef texture<int16_t, 1> TexInt16;+typedef texture<int8_t, 1> TexInt8;+typedef texture<float, 1> TexFloat;+typedef texture<char, 1> TexCChar;++static __inline__ __device__ uint8_t indexArray(TexWord8 t, const int x) { return tex1Dfetch(t,x); }+static __inline__ __device__ uint16_t indexArray(TexWord16 t, const int x) { return tex1Dfetch(t,x); }+static __inline__ __device__ uint32_t indexArray(TexWord32 t, const int x) { return tex1Dfetch(t,x); }+static __inline__ __device__ uint64_t indexArray(TexWord64 t, const int x)+{+ union { uint2 x; uint64_t y; } v;+ v.x = tex1Dfetch(t,x);+ return v.y;+}++static __inline__ __device__ int8_t indexArray(TexInt8 t, const int x) { return tex1Dfetch(t,x); }+static __inline__ __device__ int16_t indexArray(TexInt16 t, const int x) { return tex1Dfetch(t,x); }+static __inline__ __device__ int32_t indexArray(TexInt32 t, const int x) { return tex1Dfetch(t,x); }+static __inline__ __device__ int64_t indexArray(TexInt64 t, const int x)+{+ union { int2 x; int64_t y; } v;+ v.x = tex1Dfetch(t,x);+ return v.y;+}++static __inline__ __device__ float indexArray(TexFloat t, const int x) { return tex1Dfetch(t,x); }+static __inline__ __device__ char indexArray(TexCChar t, const int x) { return tex1Dfetch(t,x); }++#if defined(__LP64__)+typedef TexInt64 TexCLong;+typedef TexWord64 TexCULong;+#else+typedef TexInt32 TexCLong;+typedef TexWord32 TexCULong;+#endif++/*+ * Synonyms for C-types. NVCC will force Ints to be 32-bits.+ */+typedef TexInt8 TexCSChar;+typedef TexWord8 TexCUChar;+typedef TexInt16 TexCShort;+typedef TexWord16 TexCUShort;+typedef TexInt32 TexCInt;+typedef TexWord32 TexCUInt;+typedef TexInt64 TexCLLong;+typedef TexWord64 TexCULLong;+typedef TexFloat TexCFloat;++/*+ * Doubles, only available when compiled for Compute 1.3 and greater+ */+#if !defined(CUDA_NO_SM_13_DOUBLE_INTRINSICS)+typedef texture<int2, 1> TexDouble;+typedef TexDouble TexCDouble;++static __inline__ __device__ double indexDArray(TexDouble t, const int x)+{+ int2 v = tex1Dfetch(t,x);+ return __hiloint2double(v.y,v.x);+}+#endif++#else++typedef void* TexWord64;+typedef void* TexWord32;+typedef void* TexWord16;+typedef void* TexWord8;+typedef void* TexInt64;+typedef void* TexInt32;+typedef void* TexInt16;+typedef void* TexInt8;+typedef void* TexCShort;+typedef void* TexCUShort;+typedef void* TexCInt;+typedef void* TexCUInt;+typedef void* TexCLong;+typedef void* TexCULong;+typedef void* TexCLLong;+typedef void* TexCULLong;+typedef void* TexFloat;+typedef void* TexDouble;+typedef void* TexCFloat;+typedef void* TexCDouble;+typedef void* TexCChar;+typedef void* TexCSChar;+typedef void* TexCUChar;++void* indexArray(const void*, const int);++#endif++/* -----------------------------------------------------------------------------+ * Shapes+ * -------------------------------------------------------------------------- */++typedef int Ix;+typedef Ix DIM1;+typedef struct { Ix a,b; } DIM2;+typedef struct { Ix a,b,c; } DIM3;+typedef struct { Ix a,b,c,d; } DIM4;+typedef struct { Ix a,b,c,d,e; } DIM5;++#ifdef __cplusplus++static __inline__ __device__ int dim(DIM1 sh) { return 1; }+static __inline__ __device__ int dim(DIM2 sh) { return 2; }+static __inline__ __device__ int dim(DIM3 sh) { return 3; }+static __inline__ __device__ int dim(DIM4 sh) { return 4; }+static __inline__ __device__ int dim(DIM5 sh) { return 5; }++static __inline__ __device__ int size(DIM1 sh) { return sh; }+static __inline__ __device__ int size(DIM2 sh) { return sh.a * sh.b; }+static __inline__ __device__ int size(DIM3 sh) { return sh.a * sh.b * sh.c; }+static __inline__ __device__ int size(DIM4 sh) { return sh.a * sh.b * sh.c * sh.d; }+static __inline__ __device__ int size(DIM5 sh) { return sh.a * sh.b * sh.c * sh.d * sh.e; }++static __inline__ __device__ int index(DIM1 sh, DIM1 ix)+{+ return ix;+}++static __inline__ __device__ int index(DIM2 sh, DIM2 ix)+{+ DIM1 sh_ = sh.a;+ DIM1 ix_ = ix.a;+ return index(sh_, ix_) + ix.b * size(sh_);+}++static __inline__ __device__ int index(DIM3 sh, DIM3 ix)+{+ DIM2 sh_ = { sh.a, sh.b };+ DIM2 ix_ = { ix.a, ix.b };+ return index(sh_, ix_) + ix.c * size(sh_);+}++static __inline__ __device__ int index(DIM4 sh, DIM4 ix)+{+ DIM3 sh_ = { sh.a, sh.b, sh.c };+ DIM3 ix_ = { ix.a, ix.b, ix.c };+ return index(sh_, ix_) + ix.d * size(sh_);+}++static __inline__ __device__ int index(DIM5 sh, DIM5 ix)+{+ DIM4 sh_ = { sh.a, sh.b, sh.c, sh.d };+ DIM4 ix_ = { ix.a, ix.b, ix.c, ix.d };+ return index(sh_, ix_) + ix.e * size(sh_);+}++#else++int dim(Ix sh);+int size(Ix sh);+int index(Ix sh, Ix ix);++#endif+++/* -----------------------------------------------------------------------------+ * Tuple Types+ * -------------------------------------------------------------------------- */++#endif // __ACCELERATE_CUDA_EXTRAS_H__++// vim: filetype=cuda.c
+ cubits/accelerate_cuda_utils.h view
@@ -0,0 +1,136 @@+/* -----------------------------------------------------------------------------+ *+ * Module : Utils+ * Copyright : (c) [2009..2010] Trevor L. McDonell+ * License : BSD+ *+ * ---------------------------------------------------------------------------*/++#ifndef __UTILS_H__+#define __UTILS_H__++#include <math.h>+#include <cuda_runtime.h>++/*+ * Core assert function. Don't let this escape...+ */+#if defined(__CUDACC__) || !defined(__DEVICE_EMULATION__)+#define __assert(e, file, line) ((void)0)+#else+#define __assert(e, file, line) \+ ((void) fprintf (stderr, "%s:%u: failed assertion `%s'\n", file, line, e), abort())+#endif++/*+ * Test the given expression, and abort the program if it evaluates to false.+ * Only available in debug mode.+ */+#ifndef _DEBUG+#define assert(e) ((void)0)+#else+#define assert(e) \+ ((void) ((e) ? (void(0)) : __assert (#e, __FILE__, __LINE__)))+#endif++/*+ * Macro to insert __syncthreads() in device emulation mode+ */+#ifdef __DEVICE_EMULATION__+#define __EMUSYNC __syncthreads()+#else+#define __EMUSYNC+#endif++/*+ * Check the return status of CUDA API calls, and abort with an appropriate+ * error string on failure.+ */+#define CUDA_SAFE_CALL_NO_SYNC(call) \+ do { \+ cudaError err = call; \+ if(cudaSuccess != err) { \+ const char *str = cudaGetErrorString(err); \+ __assert(str, __FILE__, __LINE__); \+ } \+ } while (0)++#define CUDA_SAFE_CALL(call) \+ do { \+ CUDA_SAFE_CALL_NO_SYNC(call); \+ CUDA_SAFE_CALL_NO_SYNC(cudaThreadSynchronize()); \+ } while (0)+++#ifdef __cplusplus+extern "C" {+#endif++/*+ * Determine if the input is a power of two+ */+inline int+isPow2(unsigned int x)+{+ return ((x&(x-1)) == 0);+}++/*+ * Compute the next highest power of two+ */+inline unsigned int+ceilPow2(unsigned int x)+{+#if 0+ --x;+ x |= x >> 1;+ x |= x >> 2;+ x |= x >> 4;+ x |= x >> 8;+ x |= x >> 16;+ return ++x;+#endif++ return (isPow2(x)) ? x : 1u << (int) ceil(log2((double)x));+}++/*+ * Compute the next lowest power of two+ */+inline unsigned int+floorPow2(unsigned int x)+{+#if 0+ float nf = (float) n;+ return 1 << (((*(int*)&nf) >> 23) - 127);+#endif++ int exp;+ frexp(x, &exp);+ return 1 << (exp - 1);+}++/*+ * computes next highest multiple of f from x+ */+inline unsigned int+multiple(unsigned int x, unsigned int f)+{+ return ((x + (f-1)) / f);+}++/*+ * MS Excel-style CEIL() function. Rounds x up to nearest multiple of f+ */+inline unsigned int+ceiling(unsigned int x, unsigned int f)+{+ return multiple(x, f) * f;+}++#undef __assert+#ifdef __cplusplus+}+#endif+#endif+
+ cubits/backpermute.inl view
@@ -0,0 +1,32 @@+/* -----------------------------------------------------------------------------+ *+ * Module : Backpermute+ * Copyright : (c) [2009..2010] Trevor L. McDonell+ * License : BSD+ *+ * Backwards permutation (gather) an array according to the permutation+ * function. The input `shape' is that of the output array.+ *+ * bpermute :: [a] -> [Int] -> [a]+ * bpermute v is = [ v!i | i <- is ]+ *+ * ---------------------------------------------------------------------------*/++extern "C"+__global__ void+backpermute+(+ ArrOut d_out,+ const ArrIn0 d_in0,+ const Ix shape+)+{+ Ix idx;+ const Ix gridSize = __umul24(blockDim.x, gridDim.x);++ for (idx = __umul24(blockDim.x, blockIdx.x) + threadIdx.x; idx < shape; idx += gridSize)+ {+ set(d_out, idx, get0(d_in0, project(idx)));+ }+}+
+ cubits/fold.inl view
@@ -0,0 +1,92 @@+/* -----------------------------------------------------------------------------+ *+ * Module : Fold+ * Copyright : (c) [2009..2010] Trevor L. McDonell+ * License : BSD+ *+ * Reduce an array to a single value with a binary associative function+ *+ * ---------------------------------------------------------------------------*/++#include <accelerate_cuda_utils.h>++#ifndef BLOCK_SIZE+#define BLOCK_SIZE blockDim.x+#endif++#ifndef LENGTH_IS_POW_2+#define LENGTH_IS_POW_2 0+#endif+++/*+ * Compute multiple elements per thread sequentially. This reduces the overall+ * cost of the algorithm while keeping the work complexity O(n) and the step+ * complexity O(log n). c.f. Brent's Theorem optimisation.+ */+extern "C"+__global__ void+fold+(+ ArrOut d_out,+ const ArrIn0 d_in0,+ const Ix shape+)+{+ extern __shared__ TyOut scratch[];++ /*+ * Calculate first level of reduction reading into shared memory+ */+ Ix i;+ const Ix tid = threadIdx.x;+ const Ix gridSize = BLOCK_SIZE * 2 * gridDim.x;++ scratch[tid] = identity();++ /*+ * Reduce multiple elements per thread. The number is determined by the+ * number of active thread blocks (via gridDim). More blocks will result in+ * a larger `gridSize', and hence fewer elements per thread+ *+ * The loop stride of `gridSize' is used to maintain coalescing.+ */+ for (i = blockIdx.x * BLOCK_SIZE * 2 + tid; i < shape; i += gridSize)+ {+ scratch[tid] = apply(scratch[tid], get0(d_in0, i));++ /*+ * Ensure we don't read out of bounds. This is optimised away if the+ * input length is a power of two+ */+ if (LENGTH_IS_POW_2 || i + BLOCK_SIZE < shape)+ scratch[tid] = apply(scratch[tid], get0(d_in0, i+BLOCK_SIZE));+ }+ __syncthreads();++ /*+ * Now, calculate the reduction in shared memory+ */+ if (BLOCK_SIZE >= 512) { if (tid < 256) { scratch[tid] = apply(scratch[tid], scratch[tid+256]); } __syncthreads(); }+ if (BLOCK_SIZE >= 256) { if (tid < 128) { scratch[tid] = apply(scratch[tid], scratch[tid+128]); } __syncthreads(); }+ if (BLOCK_SIZE >= 128) { if (tid < 64) { scratch[tid] = apply(scratch[tid], scratch[tid+ 64]); } __syncthreads(); }++#ifndef __DEVICE_EMULATION__+ if (tid < 32)+#endif+ {+ if (BLOCK_SIZE >= 64) { scratch[tid] = apply(scratch[tid], scratch[tid+32]); __EMUSYNC; }+ if (BLOCK_SIZE >= 32) { scratch[tid] = apply(scratch[tid], scratch[tid+16]); __EMUSYNC; }+ if (BLOCK_SIZE >= 16) { scratch[tid] = apply(scratch[tid], scratch[tid+ 8]); __EMUSYNC; }+ if (BLOCK_SIZE >= 8) { scratch[tid] = apply(scratch[tid], scratch[tid+ 4]); __EMUSYNC; }+ if (BLOCK_SIZE >= 4) { scratch[tid] = apply(scratch[tid], scratch[tid+ 2]); __EMUSYNC; }+ if (BLOCK_SIZE >= 2) { scratch[tid] = apply(scratch[tid], scratch[tid+ 1]); __EMUSYNC; }+ }++ /*+ * Write the results of this block back to global memory+ */+ if (tid == 0)+ set(d_out, blockIdx.x, scratch[0]);+}+
+ cubits/map.inl view
@@ -0,0 +1,29 @@+/* -----------------------------------------------------------------------------+ *+ * Module : Map+ * Copyright : (c) 2010 Trevor L. McDonell+ * License : BSD+ *+ * Apply the function to each element of the array. Each thread processes+ * multiple elements, striding the array by the grid size.+ *+ * ---------------------------------------------------------------------------*/++extern "C"+__global__ void+map+(+ ArrOut d_out,+ const ArrIn0 d_in0,+ const Ix shape+)+{+ Ix idx;+ const Ix gridSize = __umul24(blockDim.x, gridDim.x);++ for (idx = __umul24(blockDim.x, blockIdx.x) + threadIdx.x; idx < shape; idx += gridSize)+ {+ set(d_out, idx, apply(get0(d_in0, idx)));+ }+}+
+ cubits/permute.inl view
@@ -0,0 +1,40 @@+/* -----------------------------------------------------------------------------+ *+ * Module : Permute+ * Copyright : (c) [2009..2010] Trevor L. McDonell+ * License : BSD+ *+ * Forward permutation, characterised by a function that determines for each+ * element in the source array where it should go in the target. The output+ * array should be initialised with a default value, as the permutation may be+ * between arrays of different sizes and some positions may never be touched.+ *+ * Elements from the source array are dropped for which the permutation function+ * yields the magic index `ignore`.+ *+ * ---------------------------------------------------------------------------*/++extern "C"+__global__ void+permute+(+ ArrOut d_out,+ const ArrIn0 d_in0,+ const Ix shape+)+{+ Ix dst;+ Ix idx;+ const Ix gridSize = __umul24(blockDim.x, gridDim.x);++ for (idx = __umul24(blockDim.x, blockIdx.x) + threadIdx.x; idx < shape; idx += gridSize)+ {+ dst = project(idx);++ if (dst != ignore)+ {+ set(d_out, dst, apply(get0(d_in0, idx), get0(d_out, dst)));+ }+ }+}+
+ cubits/thrust/scan_safe.inl view
@@ -0,0 +1,289 @@+/*+ * Copyright 2008-2010 NVIDIA Corporation+ *+ * Licensed under the Apache License, Version 2.0 (the "License");+ * you may not use this file except in compliance with the License.+ * You may obtain a copy of the License at+ *+ * http://www.apache.org/licenses/LICENSE-2.0+ *+ * Unless required by applicable law or agreed to in writing, software+ * distributed under the License is distributed on an "AS IS" BASIS,+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.+ * See the License for the specific language governing permissions and+ * limitations under the License.+ */++/* -----------------------------------------------------------------------------+ * A robust scan for general types+ * ---------------------------------------------------------------------------*/++template <bool inclusive, typename T>+__device__+T scan_block(T* array, T val)+{+ array[threadIdx.x] = val;++ __syncthreads();++ // copy to temporary so val and tmp have the same memory space+ if (blockDim.x > 1) { if(threadIdx.x >= 1) { T tmp = array[threadIdx.x - 1]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 2) { if(threadIdx.x >= 2) { T tmp = array[threadIdx.x - 2]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 4) { if(threadIdx.x >= 4) { T tmp = array[threadIdx.x - 4]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 8) { if(threadIdx.x >= 8) { T tmp = array[threadIdx.x - 8]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 16) { if(threadIdx.x >= 16) { T tmp = array[threadIdx.x - 16]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 32) { if(threadIdx.x >= 32) { T tmp = array[threadIdx.x - 32]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 64) { if(threadIdx.x >= 64) { T tmp = array[threadIdx.x - 64]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 128) { if(threadIdx.x >= 128) { T tmp = array[threadIdx.x - 128]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 256) { if(threadIdx.x >= 256) { T tmp = array[threadIdx.x - 256]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 512) { if(threadIdx.x >= 512) { T tmp = array[threadIdx.x - 512]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }++ if (inclusive) return val;+ else return threadIdx.x > 0 ? array[threadIdx.x - 1] : identity();+}++template <bool inclusive, typename T>+__device__+T scan_block_n(T* array, const unsigned int n, T val)+{+ array[threadIdx.x] = val;++ __syncthreads();++ if (blockDim.x > 1) { if(threadIdx.x < n && threadIdx.x >= 1) { T tmp = array[threadIdx.x - 1]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 2) { if(threadIdx.x < n && threadIdx.x >= 2) { T tmp = array[threadIdx.x - 2]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 4) { if(threadIdx.x < n && threadIdx.x >= 4) { T tmp = array[threadIdx.x - 4]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 8) { if(threadIdx.x < n && threadIdx.x >= 8) { T tmp = array[threadIdx.x - 8]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 16) { if(threadIdx.x < n && threadIdx.x >= 16) { T tmp = array[threadIdx.x - 16]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 32) { if(threadIdx.x < n && threadIdx.x >= 32) { T tmp = array[threadIdx.x - 32]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 64) { if(threadIdx.x < n && threadIdx.x >= 64) { T tmp = array[threadIdx.x - 64]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 128) { if(threadIdx.x < n && threadIdx.x >= 128) { T tmp = array[threadIdx.x - 128]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 256) { if(threadIdx.x < n && threadIdx.x >= 256) { T tmp = array[threadIdx.x - 256]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }+ if (blockDim.x > 512) { if(threadIdx.x < n && threadIdx.x >= 512) { T tmp = array[threadIdx.x - 512]; val = apply(tmp, val); } __syncthreads(); array[threadIdx.x] = val; __syncthreads(); }++ if (inclusive) return val;+ else return threadIdx.x > 0 ? array[threadIdx.x - 1] : identity();+}+++template <bool inclusive>+__device__ void+scan_intervals+(+ TyOut *sdata,+ ArrOut d_out,+ const ArrIn0 d_in0,+ ArrIn0 d_block_results,+ const Ix N,+ const Ix interval_size+)+{+ const Ix interval_begin = interval_size * blockIdx.x;+ const Ix interval_end = min(interval_begin + interval_size, N);++ TyOut val = identity();+ Ix base = interval_begin;+ Ix output = reverse ? interval_end - threadIdx.x - 1 : interval_begin + threadIdx.x;++ // process full blocks+ for(; base + blockDim.x <= interval_end; base += blockDim.x)+ {+ // read data+ val = get0(d_in0, output);++ // carry in+ if (threadIdx.x == 0 && base != interval_begin)+ {+ TyOut tmp = sdata[blockDim.x - 1];+ val = apply(tmp, val);+ }+ __syncthreads();++ // scan block+ val = scan_block<inclusive>(sdata, val);++ // write data+ set(d_out, output, val);++ // update output iterator+ if (reverse) output -= blockDim.x;+ else output += blockDim.x;+ }++ // process partially full block at end of input (if necessary)+ if (base < interval_end)+ {+ // read data+ if (base + threadIdx.x < interval_end)+ {+ val = get0(d_in0, output);+ }++ // carry in+ if (threadIdx.x == 0 && base != interval_begin)+ {+ TyOut tmp = sdata[blockDim.x - 1];+ val = apply(tmp, val);+ }+ __syncthreads();++ // scan block+ val = scan_block_n<inclusive>(sdata, interval_end - base, val);++ // write data+ if (base + threadIdx.x < interval_end)+ {+ set(d_out, output, val);+ }+ }+ __syncthreads();++ if (threadIdx.x == 0)+ {+ if (reverse)+ {+ TyOut tmp = get0(d_out, interval_begin);+ set(d_block_results, blockIdx.x, tmp);+ }+ else+ {+ TyOut tmp = get0(d_out, interval_end - 1);+ set(d_block_results, blockIdx.x, tmp);+ }+ }+}+++extern "C"+__global__ void+inclusive_scan+(+ ArrOut d_out,+ const ArrIn0 d_in0,+ ArrIn0 d_block_results,+ const Ix N,+ const Ix interval_size+)+{+ extern __shared__ TyOut sdata[];+ scan_intervals<true>(sdata, d_out, d_in0, d_block_results, N, interval_size);+}++#if 0+extern "C"+__global__ void+exclusive_scan+(+ ArrOut d_out,+ const ArrIn0 d_in0,+ ArrIn0 d_block_results,+ const Ix N,+ const Ix interval_size+)+{+ extern __shared__ TyOut sdata[];+ scan_intervals<false>(sdata, d_out, d_in0, d_block_results, N, interval_size);+}+#endif+#if 0+extern "C"+__global__ void+inclusive_update+(+ ArrOut d_out,+ ArrIn0 d_in0,+ const Ix N,+ const Ix interval_size+)+{+ const Ix interval_begin = interval_size * blockIdx.x;+ const Ix interval_end = min(interval_begin + interval_size, N);++ if (blockIdx.x == 0)+ return;++ // value to add to this segment+ TyOut sum = get0(d_in0, blockIdx.x - 1);++ // advance result iterator+ for(Ix base = interval_begin; base < interval_end; base += blockDim.x)+ {+ const Ix i = base + threadIdx.x;++ if (i < interval_end)+ {+ TyOut tmp = get0(d_out, i);+ set(d_out, i, apply(sum, tmp));+ }+ __syncthreads();+ }+}+#endif+++extern "C"+__global__ void+exclusive_update+(+ ArrOut d_out,+ ArrIn0 d_in0,+ const Ix N,+ const Ix interval_size+)+{+ extern __shared__ TyOut sdata[];++ const Ix interval_begin = interval_size * blockIdx.x;+ const Ix interval_end = min(interval_begin + interval_size, N);++ // value to add to this segment+ TyOut carry = identity();++ if (reverse)+ {+ if (blockIdx.x != gridDim.x - 1)+ {+ TyOut tmp = get0(d_in0, blockIdx.x + 1);+ carry = apply(carry, tmp);+ }+ }+ else+ {+ if (blockIdx.x != 0)+ {+ TyOut tmp = get0(d_in0, blockIdx.x - 1);+ carry = apply(carry, tmp);+ }+ }++ // advance result iterator+ Ix output = reverse ? interval_end - threadIdx.x - 1 : interval_begin + threadIdx.x;+ TyOut val = carry;++ for (Ix base = interval_begin; base < interval_end; base += blockDim.x)+ {+ const Ix i = base + threadIdx.x;++ if (i < interval_end)+ {+ TyOut tmp = get0(d_out, output);+ sdata[threadIdx.x] = apply(carry, tmp);+ }+ __syncthreads();++ if (threadIdx.x != 0)+ val = sdata[threadIdx.x - 1];++ if (i < interval_end)+ set(d_out, output, val);++ if (threadIdx.x == 0)+ val = sdata[blockDim.x - 1];++ __syncthreads();++ if (reverse) output -= blockDim.x;+ else output += blockDim.x;+ }+}+
+ cubits/zipWith.inl view
@@ -0,0 +1,30 @@+/* -----------------------------------------------------------------------------+ *+ * Module : ZipWith+ * Copyright : (c) 2010 Trevor L. McDonell+ * License : BSD+ *+ * Combine two arrays using the given binary operator. Each thread processes+ * multiple elements, striding the array by the grid size.+ *+ * ---------------------------------------------------------------------------*/++extern "C"+__global__ void+zipWith+(+ ArrOut d_out,+ const ArrIn1 d_in1,+ const ArrIn0 d_in0,+ const Ix shape+)+{+ Ix idx;+ const Ix gridSize = __umul24(blockDim.x, gridDim.x);++ for (idx = __umul24(blockDim.x, blockIdx.x) + threadIdx.x; idx < shape; idx += gridSize)+ {+ set(d_out, idx, apply(get1(d_in1, idx), get0(d_in0, idx)));+ }+}+
+ examples/rasterize/RasterizeAcc.hs view
@@ -0,0 +1,244 @@+{-+ Copyright (C) 2010 by IPwn Studios+ Released under GNU General Public License v3+-}++{-# LANGUAGE ScopedTypeVariables #-}+module RasterizeAcc where++import Control.Arrow+import Control.Parallel+import Control.Parallel.Strategies+import Data.Array.Accelerate+import Data.Array.Accelerate.Interpreter+import Data.Bits ((.&.))+import Prelude hiding (replicate, zip, unzip, map, filter, max, min, not,+ zipWith, round, uncurry, scanl, fst, snd, tail, even)+import qualified Prelude+import Debug.Trace+++type Area = ((Int, Int), (Int, Int))+type Value = ((Int, Int), Float)+type Insertion = ((Int, Int), Float)+type Facet = (Int, Int, Int)++aseq :: (NFData a, Elem a, Ix dim) => String -> Acc (Array dim a) -> Acc (Array dim a)+aseq descr = id -- use . trace descr . hseq . run++aseq1 :: (NFData a, Elem a, Ix dim, Show a) => String -> Acc (Array dim a) -> Acc (Array dim a)+aseq1 descr aarr =+ let arr = run aarr+ in use $ {-trace (descr ++ " " ++ show (arrayShape arr) ++ " " ++ show arr)-} arr++hseq :: (NFData a, Elem a, Ix dim) => Array dim a -> Array dim a+hseq arr =+ let l = toList arr `using` seqList rwhnf+ in l `seq` fromList (arrayShape arr) l++rasterize :: Exp Area+ -> Acc (Vector Value)+ -> Acc (Vector Facet) + -> Acc (Array DIM2 Float)+rasterize area values facets =+ let -- Triangle vertices sorted by X co-ordinate+ tris :: Acc (Vector (Value, Value, Value))+ tris = flip map facets $ \tri ->+ let (iA, iB, iC) = untuple tri+ in sort3Tuple lessThanX $ tuple (values ! iA, values ! iB, values ! iC)++ noOfTris = shape tris :: Exp Int++ -- Vector of (triangle index, (start column, end column))+ columnRanges :: Acc (Vector (Int, Int))+ columnRanges = aseq1 "columnRanges" $ map rangeOfColumns tris++ -- Vector of (triangle index, integer x co-ordinate of column)+ columnIndices :: Acc (Vector (Int, Int))+ columnIndices = aseq1 "columnIndices" $ flatten columnRanges++ columns :: Acc (Vector ((Int, Float, Float), (Int, Float, Float)))+ columns = aseq1 "columns" $ flip map columnIndices $ \pair ->+ let (triIx, xInt) = untuple pair+ in rowRange (tris ! triIx) xInt++ pointRanges :: Acc (Vector (Int, Int))+ pointRanges = aseq1 "pointRanges" $ flip map columns $ \col ->+ let ((yStart, _, _), (yEnd, _, _)) = (untuple *** untuple) $ untuple col+ :: ((Exp Int, Exp Float, Exp Float), (Exp Int, Exp Float, Exp Float))+ in tuple (yStart, yEnd)++ -- Vector of (column index, integer y co-ordinate of column)+ pointIndices :: Acc (Vector (Int, Int))+ pointIndices = aseq1 "pointIndices" $ flatten pointRanges++ insertions :: Acc (Vector Insertion)+ insertions = aseq1 "insertions" $ flip map pointIndices $ \pi ->+ let (colIx, yInt) = untuple pi+ (triIx, xInt) = untuple $ columnIndices ! colIx+ :: (Exp Int, Exp Int)+ ((_, yBot, vBot), (_, yTop, vTop)) =+ (untuple *** untuple) $ untuple $ columns ! colIx+ :: ((Exp Int, Exp Float, Exp Float), (Exp Int, Exp Float, Exp Float))+ -- Displace odd columns because the terrain mesh is hexagonal+ hexify yInt = even xInt ? (intToFloat yInt, intToFloat yInt + 0.5)+ v = interpolate (yBot, vBot) (yTop, vTop) (hexify yInt)+ in tuple (tuple (xInt, yInt), v)+ in toArray area insertions+ where+ ((x0,y0),(x1,y1)) = (untuple *** untuple) $ untuple area :: ((Exp Int, Exp Int), (Exp Int, Exp Int))++ -- Give the start and end of the Y value of the specified row in both+ -- floating point and integer co-ordinates. Output is a pair of+ -- (integer y, float y, value)+ rowRange :: Exp (Value, Value, Value) -> Exp Int -> Exp ((Int, Float, Float), (Int, Float, Float))+ rowRange tri xInt =+ let (a, b, c) = untuple tri+ ((axInt, ayInt), vA) = (untuple *** id) (untuple a) :: ((Exp Int, Exp Int), Exp Float)+ ((bxInt, byInt), vB) = (untuple *** id) (untuple b) :: ((Exp Int, Exp Int), Exp Float)+ ((cxInt, cyInt), vC) = (untuple *** id) (untuple c) :: ((Exp Int, Exp Int), Exp Float)+ ax = intToFloat axInt+ ay = intToFloat ayInt+ bx = intToFloat bxInt+ by = intToFloat byInt+ cx = intToFloat cxInt+ cy = intToFloat cyInt+ x = intToFloat xInt+ yAC = interpolate (ax, ay) (cx, cy) x :: Exp Float+ vAC = interpolate (ax, vA) (cx, vC) x :: Exp Float+ (yOther, vOther) = untuple (+ x <* bx ? (tuple (interpolate (ax,ay) (bx,by) x, interpolate (ax,vA) (bx,vB) x),+ tuple (interpolate (bx,by) (cx,cy) x, interpolate (bx,vB) (cx,vC) x))+ ) :: (Exp Float, Exp Float)+ -- Order AC and Other so that y is increasing+ (yBot, vBot, yTop, vTop) = untuple (+ yAC <=* yOther ? (tuple (yAC, vAC, yOther, vOther),+ tuple (yOther, vOther, yAC, vAC))+ ) :: (Exp Float, Exp Float, Exp Float, Exp Float)+ yStart = max y0 (roundFloatToInt yBot)+ yEnd = min (y1+1) (roundFloatToInt yTop)+ in tuple (tuple (yStart, yBot, vBot), tuple (yEnd, yTop, vTop))++ rangeOfColumns :: Exp (Value, Value, Value) -> Exp (Int, Int)+ rangeOfColumns tri =+ let (a, _, c) = untuple tri :: (Exp Value, Exp Value, Exp Value)+ (xyA, _) = untuple a :: (Exp (Int, Int), Exp Float)+ (xA, _) = untuple xyA :: (Exp Int, Exp Int)+ (xyC, _) = untuple c :: (Exp (Int, Int), Exp Float)+ (xC, _) = untuple xyC :: (Exp Int, Exp Int)+ in tuple (x0 `max` xA, (x1 + 1) `min` xC)++-- | Flatten a list of ranges with an exclusive upper value into a list of+-- indices into the concatenated ranges in the form (input ix, value in range). e.g.+--+-- > [(5,8),(10,15),(3,4)]+--+-- > [(0,5),(0,6),(0,7),(1,10),(1,11),(1,12),(1,13),(1,14),(2,3)]+flatten :: Acc (Vector (Int, Int))+ -> Acc (Vector (Int, Int))+flatten ranges0 =+ let -- ensure the ranges are not decreasing+ ranges = flip map ranges0 $ \ab ->+ let (a, b) = untuple ab+ in tuple (a, a `max` b)+ noOfRanges = shape ranges :: Exp Int++ rangeWidths :: Acc (Vector Int)+ rangeWidths = aseq1 "f.rangeWidths" $ map (uncurry $ flip (-)) ranges++ -- The start position of each column in a yet-to-be-created array of columns+ (columnOffsets, noOfCols) = second (! constant ()) $ scanl (+) 0 $ rangeWidths+ :: (Acc (Vector Int), Exp Int)++ -- Input indices for each of the output elements, e.g. for the example+ -- above, [0,0,0,1,1,1,1,1,2]+ rangeIndices :: Acc (Vector Int)+ rangeIndices = aseq1 "f.rangeIndices" $+ let ones = replicate noOfRanges (unit 1) :: Acc (Vector Int)+ zeroes = replicate (noOfCols + 1) (unit 0) :: Acc (Vector Int)+ steps = permute (+) zeroes (columnOffsets !) ones+ in tail $ Prelude.fst $ scanl (+) (-1) steps++ columnIndices :: Acc (Vector Int)+ columnIndices = aseq1 "f.columnIndices" $+ -- [10 - 8 + 1, 3 - 15 + 1] + -- [3, -11]+ -- 5 + let ones = use $ run $ replicate (noOfCols + 1) (unit 1) :: Acc (Vector Int)+ -- ([5,10,3], [8,15,4]) + (rangeStarts, rangeEnds) = unzip ranges+ -- [3, -11]+ deltas = use $ run $ map (1+) $ zipWith (-) (tail rangeStarts) rangeEnds+ deltas_m1 = map (\x -> x - 1) deltas+ -- [1, 1, 1, 3, 1, 1, 1, 1,-11, 1]+ changes = use $ run $ permute (+) ones (\ix -> columnOffsets ! (ix + 1)) deltas_m1+ -- [5, 6, 7,10,11,12,13, 14, 3]+ in tail $ Prelude.fst $ scanl (+) ((rangeStarts ! 0) - 1) changes++ in zip rangeIndices columnIndices++tail :: Elem a => Acc (Vector a) -> Acc (Vector a)+tail xs = backpermute (shape xs - 1) (1+) xs++even :: Exp Int -> Exp Bool+even x = (x .&. 1) ==* 0++interpolate :: (Exp Float, Exp Float) -> (Exp Float, Exp Float) -> Exp Float -> Exp Float+interpolate (t0, x0) (t1, x1) t = (t - t0) * (x1 - x0) / (t1 - t0) + x0++-- | Give an array of values [0..length xs-1], e.g. [8,2,3,4] -> [0,1,2,3]+indicesOf :: Elem a => Acc (Vector a) -> Acc (Vector Int)+indicesOf = Prelude.fst . scanl (+) 0 . map (const 1)++lessThanX :: Exp Value -> Exp Value -> Exp Bool+lessThanX a b =+ let (xyA, _) = untuple a :: (Exp (Int, Int), Exp Float)+ (xA, _) = untuple xyA :: (Exp Int, Exp Int)+ (xyB, _) = untuple b :: (Exp (Int, Int), Exp Float)+ (xB, _) = untuple xyB :: (Exp Int, Exp Int)+ in xA <* xB++sort3Tuple :: forall a . (Elem a) =>+ (Exp a -> Exp a -> Exp Bool) -- ^ Less-than function+ -> Exp (a, a, a) -- ^ Tuple+ -> Exp (a, a, a)+sort3Tuple lessThan = shuttle1 . untuple+ where+ -- Shuttle sort+ shuttle1 :: (Exp a, Exp a, Exp a) -> Exp (a, a, a)+ shuttle1 (a, b, c) = a `lessThan` b ? (shuttle2 (a, b, c), shuttle2 (b, a, c))++ shuttle2 :: (Exp a, Exp a, Exp a) -> Exp (a, a, a)+ shuttle2 (a, b, c) = b `lessThan` c ? (tuple (a, b, c), shuttle3 (a, c, b))++ shuttle3 :: (Exp a, Exp a, Exp a) -> Exp (a, a, a)+ shuttle3 (a, b, c) = a `lessThan` b ? (tuple (a, b, c), tuple (b, a, c))++prop_sort3Tuple :: (Int, Int, Int) -> Bool+prop_sort3Tuple triple =+ let (a, b, c) = head $ toList $ run (map (sort3Tuple (<*)) $ unit $ constant triple)+ in a <= b && b <= c++toArray :: Exp Area+ -> Acc (Vector Insertion)+ -> Acc (Array DIM2 Float)+toArray area insertions =+ let (bl, tr) = untuple area+ (x0, y0) = untuple bl+ (x1, y1) = untuple tr+ w = x1 - x0 + 1+ h = y1 - y0 + 1 + z = zeroArray (tuple (h, w))+ (ixs, values) = unzip insertions+ perm :: Exp Int -> Exp (Int, Int)+ perm ix =+ let (x, y) = untuple (ixs ! ix)+ in+ x >=* x0 &&* x <=* x1 &&*+ y >=* y0 &&* y <=* y1+ ? (tuple (y - y0, x - x0), ignore)+ in permute const z perm values++zeroArray :: Exp (Int, Int) -> Acc (Array DIM2 Float)+zeroArray dim = replicate dim (unit 0)+
+ examples/rasterize/rasterize-test1.txt view
@@ -0,0 +1,4 @@+[((-267,-201),33.957397),((-244,-202),-69.39026),((-226,-217),36.21704),((-287,-181),-15.463562),((-309,-170),-11.445068),((-280,-273),39.814148),((-324,-236),79.39956),((-349,-182),59.562397),((-316,-199),29.185278),((-305,-213),43.06239),((-258,-179),-97.86456),((-362,-201),56.988422),((-335,-252),121.0145),((-318,-277),66.3733),((-235,-275),136.13342),((-295,-196),11.120207)]+[(5,0,9),(6,8,11),(6,9,8),(5,9,6),(6,13,5),(6,12,13),(11,8,7),(8,4,7),(4,8,15),(8,9,15),(9,0,15),(15,0,3),(4,15,3),(0,10,3),(0,1,10),(2,0,1),(5,2,0),(14,2,5)]+((-321,-257),(-255,-191))+[72.88643,73.098595,73.31075,73.52292,73.735085,73.94725,74.15941,74.371574,74.58374,74.7959,75.008064,75.22023,75.432396,75.644554,75.85672,76.068886,76.281044,76.49321,76.68934,76.195625,75.70191,75.208206,74.71449,74.22078,73.72707,72.55211,71.27393,69.99576,68.71758,67.43941,66.161224,64.88305,63.604874,62.3267,61.048523,59.795395,58.557297,57.319202,56.081104,54.843006,53.604908,52.366814,51.128716,49.890617,48.65252,47.41442,46.176323,44.93823,43.70013,42.462032,41.223938,39.98584,38.74774,37.509644,36.271545,35.03345,33.795353,32.55726,32.613297,33.17915,33.745003,32.81883,31.77035,30.721872,29.673395,28.624916,27.576439,72.05909,72.271255,72.48342,72.69558,72.907745,73.11991,73.33208,73.544235,73.7564,73.96857,74.180725,74.39289,74.60506,74.81722,75.02938,75.24155,75.45371,75.66587,75.62136,75.12765,74.633934,74.14023,73.646515,73.1528,72.659096,72.16538,71.547806,70.26963,68.991455,67.71327,66.4351,65.15692,63.878746,62.600567,61.32239,60.044212,58.766037,57.48786,56.209686,54.91147,53.67337,52.435272,51.197174,49.959076,48.72098,47.482883,46.244785,45.006687,43.76859,42.530495,41.292397,40.0543,38.8162,37.578102,36.340004,35.101906,33.863808,32.62571,31.701357,32.26721,32.9309,31.882423,30.833946,29.78547,28.736992,27.688515,26.640038,71.44391,71.656075,71.86824,72.0804,72.292564,72.50473,72.716896,72.929054,73.14122,73.353386,73.565544,73.77771,73.989876,74.20204,74.4142,74.626366,74.83853,74.553375,74.05966,73.565956,73.07224,72.57853,72.08482,71.59111,71.097404,70.60369,70.10998,69.26532,67.987144,66.70897,65.43079,64.15262,62.87444,61.59626,60.318085,59.03991,57.76173,56.483555,55.205376,53.9272,52.649025,51.370846,50.09267,48.81449,47.551346,46.313248,45.075153,43.837055,42.59896,41.360863,40.122765,38.884666,37.646572,36.408478,35.17038,33.93228,32.694183,31.456089,31.355259,31.921112,30.946014,29.897537,28.84906,27.800583,26.752106,25.703629,24.655151,70.61658,70.828735,71.0409,71.25307,71.465225,71.67739,71.88956,72.10172,72.31388,72.52605,72.73821,72.95037,73.16254,73.3747,73.58687,73.79903,73.9791,73.4854,72.991684,72.49798,72.004265,71.51056,71.016846,70.52314,70.02943,69.53572,69.04201,68.5483,68.261024,66.98285,65.704666,64.42649,63.148315,61.87014,60.59196,59.31378,58.035606,56.75743,55.47925,54.201077,52.922897,51.644722,50.366547,49.088367,47.81019,46.532013,45.253838,43.975662,42.69748,41.429325,40.191227,38.95313,37.71503,36.476933,35.23884,34.00074,32.76264,31.524544,30.443316,31.058088,30.009611,28.961134,27.912657,26.864182,25.815704,24.767227,23.71875,70.0014,70.21356,70.42573,70.63789,70.85006,71.06222,71.27438,71.48655,71.69871,71.91087,72.12304,72.335205,72.54736,72.75953,72.971695,72.91113,72.41742,71.923706,71.43,70.93629,70.44258,69.94887,69.45516,68.96145,68.467735,67.97403,67.480316,66.98661,66.4929,65.97854,64.70036,63.422188,62.14401,60.865833,59.587658,58.30948,57.031303,55.753124,54.47495,53.19677,51.918594,50.64042,49.36224,48.084064,46.805885,45.52771,44.249535,42.971355,41.69318,40.415,39.136826,37.85865,36.58047,35.307304,34.06921,32.831112,31.593016,30.35492,30.097223,29.073206,28.024729,26.976252,25.927776,24.8793,23.830822,22.782345,21.733868,69.17406,69.386215,69.59838,69.81055,70.02271,70.23487,70.44704,70.6592,70.87137,71.08353,71.29569,71.50786,71.72002,71.93218,72.33685,71.84315,71.349434,70.85573,70.362015,69.86831,69.374596,68.88089,68.38718,67.89346,67.39976,66.906044,66.41234,65.918625,65.42492,64.931206,64.4375,63.696056,62.41788,61.139706,59.861526,58.58335,57.305172,56.026997,54.748817,53.470642,52.192467,50.914288,49.636112,48.357933,47.079758,45.801582,44.523407,43.245228,41.96705,40.688873,39.410698,38.13252,36.85434,35.576164,34.29799,33.019814,31.741634,30.463455,29.185278,28.1368,27.088324,26.039845,24.991367,23.94289,22.894413,21.845936,20.797459,68.558876,68.77104,68.98321,69.19537,69.40753,69.6197,69.83186,70.04402,70.25619,70.46835,70.68052,70.89268,71.10484,71.26888,70.77518,70.28146,69.78776,69.294044,68.80034,68.306625,67.81291,67.31921,66.82549,66.33179,65.83807,65.34437,64.850655,64.35695,63.863235,63.369526,62.875816,62.382107,61.413593,60.135418,58.85724,57.579063,56.300884,55.02271,53.74453,52.466354,51.188175,49.909996,48.63182,47.353645,46.075466,44.797287,43.51911,42.240932,40.962753,39.684578,38.406403,37.128227,35.850044,34.57187,33.293694,32.015514,30.737335,29.288607,27.883595,26.647572,25.411549,24.175524,23.006483,21.958006,20.909529,19.861052,18.812574,67.731544,67.9437,68.15587,68.368034,68.5802,68.79236,69.004524,69.21669,69.428856,69.641014,69.85318,70.065346,70.27751,70.200905,69.7072,69.213486,68.71977,68.22607,67.73235,67.23865,66.744934,66.25122,65.757515,65.2638,64.770096,64.27638,63.782673,63.288963,62.79525,62.30154,61.80783,61.31412,60.82041,60.409267,59.131092,57.852917,56.574738,55.296562,54.018387,52.740208,51.462032,50.183853,48.905678,47.6275,46.349323,45.071144,43.79297,42.514793,41.236614,39.95844,38.68026,37.402084,36.12391,34.845734,33.567554,32.389698,30.890816,29.391935,27.817951,26.581928,25.345905,24.109882,22.873857,21.637835,20.401812,19.165787,17.876179,67.11636,67.32853,67.540695,67.75285,67.96502,68.177185,68.38934,68.60151,68.813675,69.02583,69.238,69.450165,69.13292,68.63921,68.1455,67.651794,67.15808,66.664375,66.17066,65.676956,65.18324,64.68954,64.19582,63.702114,63.208405,62.714695,62.220985,61.727276,61.233566,60.739857,60.246147,59.752438,59.258728,58.76502,58.126804,56.84863,55.57045,54.292274,53.014095,51.73592,50.45774,49.179565,47.901386,46.62321,45.34503,44.066856,42.788677,41.510498,40.232323,38.954147,37.67597,36.39779,35.119614,33.84144,32.493034,30.994148,29.495264,27.996378,26.516268,25.280245,24.044222,22.808199,21.572174,20.336151,19.100128,17.864105,16.628082,66.289024,66.50119,66.71335,66.925514,67.13768,67.349846,67.562004,67.77417,67.986336,68.1985,68.41066,68.558655,68.06494,67.571236,67.07752,66.58382,66.0901,65.5964,65.102684,64.60898,64.115265,63.621555,63.127846,62.634136,62.140427,61.646717,61.153008,60.659298,60.16559,59.671875,59.17817,58.684456,58.190746,57.697037,57.203327,56.709618,55.844322,54.566143,53.287968,52.00979,50.73161,49.453434,48.175255,46.897076,45.618896,44.34072,43.062542,41.784363,40.506187,39.228012,37.94983,36.671654,35.393475,34.095234,32.596348,31.097466,29.598581,28.099697,26.600815,25.214584,23.978561,22.742538,21.506516,20.27049,19.034468,17.798443,16.56242,65.67385,65.88602,66.098175,66.31034,66.52251,66.73467,66.94683,67.159,67.37116,67.58333,67.49068,66.99696,66.50326,66.009544,65.51584,65.022125,64.52842,64.034706,63.540997,63.047287,62.553577,62.059868,61.56616,61.07245,60.57874,60.08503,59.591316,59.097607,58.603897,58.110188,57.616478,57.12277,56.62906,56.13535,55.64164,55.147926,54.65422,53.56184,52.28366,51.005486,49.72731,48.44913,47.170956,45.892776,44.6146,43.336422,42.058247,40.780067,39.501892,38.223713,36.945538,35.66736,34.19857,32.699684,31.200798,29.701912,28.203024,26.704138,25.205252,23.912903,22.676878,21.440855,20.20483,18.968807,17.732784,16.496761,15.260737,64.846504,65.05867,65.270836,65.482994,65.69516,65.907326,66.11949,66.33165,66.543816,66.91641,66.4227,65.928986,65.43528,64.94157,64.44786,63.954147,63.460438,62.96673,62.47302,61.97931,61.4856,60.99189,60.49818,60.00447,59.510757,59.017048,58.52334,58.02963,57.53592,57.04221,56.5485,56.054787,55.56108,55.067368,54.57366,54.07995,53.58624,53.09253,52.557533,51.279358,50.00118,48.723,47.444824,46.166645,44.888466,43.61029,42.33211,41.053932,39.775753,38.497574,37.299656,35.80077,34.301888,32.803005,31.304123,29.80524,28.306358,26.807476,25.308592,23.84726,22.611237,21.375212,20.139189,18.903166,17.667143,16.431118,15.195095,64.23133,64.4435,64.65566,64.86782,65.07999,65.29215,65.50432,65.71648,65.848434,65.35472,64.861015,64.3673,63.873592,63.379883,62.88617,62.39246,61.89875,61.40504,60.91133,60.41762,59.923912,59.430202,58.936493,58.44278,57.94907,57.45536,56.96165,56.46794,55.97423,55.480522,54.98681,54.4931,53.99939,53.50568,53.01197,52.518257,52.02455,51.530838,51.03713,50.27505,48.996876,47.718697,46.44052,45.162342,43.884167,42.605988,41.327812,40.049633,38.771458,37.402992,35.904106,34.40522,32.906338,31.407454,29.908567,28.409683,26.910799,25.411915,23.91303,22.545576,21.309553,20.073528,18.837505,17.601482,16.365458,15.129436,13.893411,63.403996,63.616158,63.828323,64.04049,64.25265,64.46481,64.67698,64.889145,64.78046,64.28674,63.793034,63.299324,62.805614,62.311905,61.818195,61.324482,60.830772,60.337063,59.843353,59.349644,58.855934,58.36222,57.86851,57.3748,56.881092,56.387383,55.893673,55.399963,54.90625,54.41254,53.91883,53.42512,52.93141,52.437702,51.943993,51.45028,50.95657,50.46286,49.96915,49.47544,49.270744,47.99257,46.71439,45.43621,44.15803,42.879852,41.601677,40.323498,39.005188,37.506306,36.00742,34.508537,33.009655,31.510769,30.011887,28.513,27.014118,25.515234,24.01635,22.479916,21.243893,20.00787,18.771845,17.535822,16.299799,15.063775,13.827751,62.788815,63.00098,63.213142,63.42531,63.63747,63.849632,64.0618,63.71247,63.21876,62.725048,62.23134,61.73763,61.24392,60.75021,60.2565,59.76279,59.26908,58.77537,58.281662,57.787952,57.294243,56.80053,56.306824,55.81311,55.3194,54.82569,54.33198,53.838272,53.344563,52.850853,52.357143,51.863434,51.36972,50.876015,50.3823,49.88859,49.394882,48.901173,48.407463,47.913754,47.420044,46.926334,45.71009,44.43191,43.153732,41.875557,40.597378,39.108524,37.609642,36.11076,34.611877,33.11299,31.614109,30.115225,28.61634,27.117458,25.618576,24.119692,22.620808,21.17825,19.942226,18.706203,17.47018,16.234156,14.998133,13.76211,12.526086,61.96148,62.17364,62.385807,62.59797,62.810135,63.022297,63.138203,62.644493,62.150784,61.657074,61.16336,60.66965,60.17594,59.68223,59.188522,58.694813,58.201103,57.707394,57.213684,56.71997,56.226265,55.73255,55.238842,54.745132,54.251423,53.757713,53.264004,52.770294,52.276585,51.782875,51.28916,50.795452,50.301743,49.808033,49.314323,48.820614,48.326904,47.833195,47.339485,46.84577,46.352066,45.858353,45.364647,44.705784,43.4276,42.20961,40.710728,39.211845,37.71296,36.214077,34.715195,33.216312,31.717428,30.218544,28.719662,27.22078,25.721895,24.223011,22.724129,21.11259,19.876566,18.640543,17.40452,16.168495,14.932472,13.696449,12.460425,61.346302,61.558464,61.77063,61.98279,62.194958,62.07022,61.57651,61.0828,60.589092,60.095383,59.601673,59.10796,58.61425,58.12054,57.62683,57.13312,56.639412,56.145702,55.651993,55.158283,54.664574,54.17086,53.677155,53.18344,52.68973,52.196022,51.702312,51.208603,50.714893,50.221184,49.727474,49.233765,48.74005,48.246346,47.752632,47.258923,46.765213,46.271503,45.777794,45.284084,44.790375,44.296665,43.802956,43.309242,42.312946,40.814064,39.315178,37.816296,36.31741,34.818527,33.31964,31.820757,30.321873,28.822989,27.324104,25.82522,24.326334,22.827452,21.328566,19.829681,18.574883,17.33886,16.102837,14.866813,13.63079,12.394766,11.158743,60.51896,60.73112,60.943283,61.15545,61.495956,61.002247,60.508537,60.014828,59.52112,59.02741,58.5337,58.039986,57.546276,57.052567,56.558857,56.065147,55.571438,55.07773,54.58402,54.09031,53.596596,53.10289,52.609177,52.115467,51.621758,51.128048,50.63434,50.14063,49.64692,49.15321,48.6595,48.165787,47.672077,47.178368,46.684658,46.19095,45.69724,45.20353,44.70982,44.21611,43.722397,43.22869,42.916306,42.875923,43.49686,41.362335,39.418503,37.919617,36.420734,34.92185,33.422962,31.92408,30.425194,28.926311,27.427425,25.928541,24.429657,22.930773,21.431889,19.933002,18.509224,17.2732,16.037176,14.801153,13.56513,12.329105,11.093082,59.903786,60.115948,60.328114,60.42798,59.93427,59.44056,58.94685,58.45314,57.959427,57.465717,56.972008,56.4783,55.98459,55.49088,54.99717,54.503456,54.009747,53.516037,53.022327,52.528618,52.03491,51.5412,51.047485,50.553776,50.060066,49.566357,49.072647,48.578934,48.085228,47.591515,47.097805,46.604095,46.110386,45.616676,45.122963,44.629257,44.135544,43.641834,43.148125,42.790413,42.75003,42.709644,42.669262,42.628876,42.588493,40.72952,38.595005,36.524055,35.025173,33.52629,32.02741,30.528524,29.029642,27.530758,26.031876,24.532993,23.034111,21.535229,20.036345,18.537462,17.20756,15.971535,14.735512,13.499489,12.263464,11.027441,9.791417,59.076443,59.28861,59.50077,59.359997,58.866287,58.372578,57.87887,57.38516,56.89145,56.39774,55.90403,55.410316,54.91661,54.422897,53.929188,53.43548,52.94177,52.44806,51.95435,51.46064,50.96693,50.47322,49.979507,49.485798,48.99209,48.49838,48.00467,47.51096,47.01725,46.52354,46.02983,45.536118,45.042408,44.5487,44.05499,43.56128,43.06757,42.664524,42.624138,42.583755,42.54337,42.502987,42.4626,42.42222,42.381832,42.23124,40.09673,37.96222,35.82771,33.629635,32.13075,30.631865,29.132978,27.634094,26.135208,24.636322,23.137438,21.638554,20.139668,18.640781,17.141897,15.905873,14.66985,13.433826,12.1978035,10.96178,9.725756,58.461266,58.67343,58.29202,57.798306,57.304596,56.810886,56.317177,55.823467,55.329758,54.83605,54.34234,53.848625,53.35492,52.861206,52.367496,51.873787,51.380077,50.886368,50.39266,49.89895,49.405235,48.91153,48.417816,47.924107,47.430397,46.936687,46.442978,45.94927,45.45556,44.961845,44.46814,43.974426,43.480717,42.987007,42.53863,42.49825,42.457863,42.41748,42.377094,42.33671,42.296326,42.255943,42.215557,42.175175,42.13479,41.59842,39.46391,37.3294,35.194893,33.060383,30.925877,29.236301,27.737415,26.23853,24.739645,23.240759,21.741875,20.242989,18.744102,17.245216,15.840212,14.604189,13.368165,12.132142,10.896118,9.660095,8.424072,57.63393,57.71775,57.22404,56.73033,56.23662,55.74291,55.2492,54.75549,54.26178,53.76807,53.27436,52.78065,52.28694,51.793232,51.299522,50.80581,50.312103,49.81839,49.32468,48.83097,48.33726,47.84355,47.349842,46.856133,46.362423,45.868713,45.375,44.881294,44.38758,43.89387,43.40016,42.906452,42.412743,42.372356,42.331974,42.291588,42.251205,42.21082,42.170437,42.13005,42.08967,42.049282,42.0089,41.968513,41.92813,41.887745,40.965626,38.831116,36.6966,34.56209,32.427578,30.293068,28.158554,26.341858,24.842974,23.344091,21.84521,20.346325,18.847443,17.34856,15.774572,14.538548,13.302525,12.066502,10.830479,9.594455,8.358431,56.64977,56.15606,55.66235,55.16864,54.67493,54.18122,53.68751,53.1938,52.70009,52.20638,51.71267,51.21896,50.72525,50.23154,49.73783,49.24412,48.750412,48.256702,47.762993,47.269283,46.775574,46.28186,45.788155,45.29444,44.800735,44.307022,43.813313,43.319603,42.825893,42.332184,42.246464,42.20608,42.165695,42.125313,42.084927,42.044544,42.004158,41.963776,41.92339,41.883007,41.84262,41.80224,41.761852,41.72147,41.681084,41.6407,40.3328,38.19829,36.06378,33.92927,31.794762,29.660252,27.525742,25.39123,23.44741,21.948528,20.449644,18.950762,17.45188,15.952996,14.472889,13.236865,12.000841,10.764818,9.528795,8.29277,7.0567474,55.581787,55.088078,54.594368,54.10066,53.60695,53.11324,52.61953,52.12582,51.63211,51.138397,50.64469,50.150978,49.65727,49.16356,48.66985,48.17614,47.68243,47.18872,46.69501,46.2013,45.707592,45.213882,44.72017,44.22646,43.73275,43.239044,42.74533,42.160957,42.120575,42.08019,42.039806,41.99942,41.959038,41.91865,41.87827,41.837883,41.7975,41.757114,41.716732,41.676346,41.635963,41.595577,41.555195,41.51481,41.474426,41.43404,41.834522,39.700012,37.5655,35.430984,33.296474,31.16196,29.027447,26.892935,24.758423,22.62391,20.552965,19.054081,17.555199,16.056316,14.557432,13.171205,11.935182,10.699158,9.463135,8.227112,6.9910884,54.0201,53.52639,53.03268,52.53897,52.04526,51.55155,51.057842,50.564133,50.070423,49.576714,49.083004,48.589294,48.095585,47.601875,47.108166,46.614456,46.120743,45.627037,45.133324,44.639618,44.145905,43.6522,43.158485,42.66478,42.171066,41.994682,41.9543,41.913914,41.87353,41.833145,41.792763,41.752377,41.711994,41.671608,41.631226,41.59084,41.550457,41.51007,41.46969,41.429302,41.38892,41.348534,41.30815,41.267765,41.227383,41.186996,41.146614,39.067223,36.93271,34.7982,32.66369,30.529177,28.394665,26.260155,24.125643,21.99113,19.856619,17.722107,16.15965,14.660761,13.161869,11.869519,10.633496,9.397472,8.161449,6.8576865,5.5354505,52.952133,52.458424,51.96471,51.471,50.97729,50.48358,49.98987,49.49616,49.00245,48.50874,48.01503,47.521317,47.027607,46.533897,46.040184,45.546474,45.052765,44.559055,44.065346,43.571632,43.077923,42.584213,41.909176,41.86879,41.828407,41.78802,41.74764,41.707253,41.66687,41.626484,41.5861,41.545715,41.505333,41.464947,41.424564,41.38418,41.343796,41.30341,41.263027,41.22264,41.18226,41.141872,41.10149,41.061104,41.02072,40.980335,40.939953,40.56891,38.4344,36.29989,34.16538,32.03087,29.896358,27.761848,25.627337,23.492826,21.358316,19.223804,17.089294,14.764094,13.265211,11.803879,10.567856,9.319516,7.9972796,6.6750426,5.3528056,51.39044,50.896732,50.403023,49.90931,49.4156,48.92189,48.42818,47.93447,47.440758,46.94705,46.45334,45.95963,45.46592,44.972206,44.4785,43.984787,43.491077,42.997368,42.50366,42.00995,41.7429,41.702515,41.662132,41.621746,41.581364,41.540977,41.500595,41.46021,41.419827,41.37944,41.339058,41.29867,41.25829,41.217903,41.17752,41.137135,41.096752,41.056366,41.015984,40.975597,40.935215,40.89483,40.854446,40.81406,40.773678,40.73329,40.69291,39.93612,37.801605,35.667095,33.53258,31.398071,29.26356,27.129047,24.994534,22.860023,20.725512,18.591,16.456486,14.321976,12.187464,10.459088,9.136852,7.8146152,6.492378,5.1701417,3.8479047,50.322464,49.828754,49.335045,48.841335,48.347626,47.853912,47.360203,46.866493,46.372784,45.879074,45.385365,44.891655,44.39794,43.904232,43.410522,42.916813,42.423103,41.929394,41.61701,41.576626,41.53624,41.495857,41.45547,41.41509,41.374702,41.33432,41.293934,41.25355,41.213165,41.172783,41.132397,41.092014,41.05163,41.011246,40.97086,40.930477,40.89009,40.84971,40.809322,40.76894,40.728554,40.68817,40.647785,40.607403,40.567017,40.526634,40.486248,41.437805,39.303295,37.168785,35.034275,32.899765,30.765251,28.630741,26.496231,24.36172,22.22721,20.092697,17.958187,15.823677,13.689163,11.575939,9.560631,7.631956,6.309719,4.9874825,3.665246,48.760773,48.267063,47.773354,47.27964,46.78593,46.29222,45.79851,45.304802,44.811092,44.317383,43.82367,43.32996,42.83625,42.34254,41.84883,41.49112,41.450733,41.41035,41.369965,41.329582,41.289196,41.248814,41.208427,41.168045,41.12766,41.087276,41.04689,41.006508,40.96612,40.92574,40.885353,40.84497,40.804585,40.764202,40.723816,40.683434,40.643047,40.602665,40.56228,40.521896,40.48151,40.441128,40.40074,40.36036,40.319973,40.27959,40.239204,40.198822,38.670506,36.53599,34.40148,32.266968,30.132454,27.997942,25.86343,23.728918,21.594406,19.459894,17.32538,15.190868,13.056356,11.024018,9.008709,6.9934,4.9780912,3.482587,2.1603503,47.69279,47.19908,46.70537,46.211662,45.717953,45.224243,44.730534,44.236824,43.74311,43.2494,42.75569,42.261982,41.768272,41.365227,41.32484,41.28446,41.244072,41.20369,41.163303,41.12292,41.082535,41.042152,41.001766,40.961384,40.920998,40.880615,40.84023,40.799847,40.75946,40.719078,40.67869,40.63831,40.597923,40.55754,40.517155,40.476772,40.436386,40.396004,40.355618,40.315235,40.27485,40.234467,40.19408,40.153698,40.11331,40.07293,40.032543,39.99216,40.172226,38.037712,35.9032,33.768684,31.63417,29.499657,27.365143,25.230629,23.096115,20.961601,18.827087,16.692574,14.502715,12.487406,10.472097,8.456789,6.4414797,4.4261703,2.410862,46.131104,45.637394,45.143684,44.64997,44.15626,43.66255,43.168842,42.675133,42.18142,41.68771,41.239334,41.19895,41.158566,41.118183,41.077797,41.037415,40.99703,40.956646,40.91626,40.875877,40.83549,40.79511,40.754723,40.71434,40.673954,40.63357,40.593185,40.552803,40.512417,40.472034,40.43165,40.391266,40.35088,40.310497,40.27011,40.22973,40.189342,40.14896,40.108574,40.06819,40.027805,39.987423,39.947037,39.906654,39.86627,39.825886,39.7855,39.745117,39.539402,37.404892,35.270382,33.13587,31.001362,28.866852,26.732342,24.597832,22.463322,20.328812,18.194302,16.059793,13.950823,11.935511,9.920198,7.904886,5.889573,3.87426,1.8589478,45.063126,44.569416,44.075706,43.581993,43.088284,42.594574,42.100864,41.607155,41.113445,41.07306,41.032677,40.99229,40.95191,40.911522,40.87114,40.830753,40.79037,40.749985,40.709602,40.669216,40.628834,40.588448,40.548065,40.50768,40.467297,40.42691,40.386528,40.34614,40.30576,40.265373,40.22499,40.184605,40.144222,40.103836,40.063454,40.023067,39.982685,39.9423,39.901917,39.86153,39.821148,39.78076,39.74038,39.699993,39.65961,39.619225,39.578842,39.538456,39.498074,38.906612,36.7721,34.63759,32.503075,30.368565,28.234055,26.09954,23.96503,21.830519,19.696007,17.561495,15.414211,13.3989,11.383588,9.368277,7.3529644,5.337652,3.322341,43.501434,43.007725,42.514015,42.020306,41.526596,41.032887,40.947166,40.906784,40.866398,40.826015,40.78563,40.745247,40.70486,40.66448,40.624092,40.58371,40.543324,40.50294,40.462555,40.422173,40.381786,40.341404,40.301018,40.260635,40.22025,40.179867,40.13948,40.0991,40.058712,40.01833,39.977943,39.93756,39.897175,39.856792,39.816406,39.776024,39.735638,39.695255,39.65487,39.614487,39.5741,39.53372,39.493332,39.45295,39.412563,39.37218,39.331795,39.291412,39.251026,38.27379,36.13928,34.00477,31.870258,29.735748,27.601238,25.466726,23.332218,21.197706,19.063196,16.928686,14.862289,12.846978,10.831667,8.816355,6.8010445,4.7857323,2.770422,42.433453,41.939743,41.446033,40.86166,40.821278,40.78089,40.74051,40.700123,40.65974,40.619354,40.57897,40.538586,40.498203,40.457817,40.417435,40.37705,40.336666,40.29628,40.255898,40.21551,40.17513,40.134743,40.09436,40.053974,40.01359,39.973206,39.932823,39.892437,39.852055,39.81167,39.771286,39.7309,39.690517,39.65013,39.60975,39.569363,39.52898,39.488594,39.44821,39.407825,39.367443,39.327057,39.286674,39.24629,39.205906,39.16552,39.125137,39.08475,39.04437,39.77551,37.641,35.506485,33.37197,31.237461,29.10295,26.968437,24.833923,22.699413,20.5649,18.430387,16.325676,14.310366,12.2950535,10.279743,8.264433,6.2491217,4.2338104,40.87176,40.695385,40.655003,40.614616,40.574234,40.533848,40.493465,40.45308,40.412697,40.37231,40.33193,40.291542,40.25116,40.210773,40.170387,40.130005,40.08962,40.049236,40.00885,39.968468,39.92808,39.8877,39.847313,39.80693,39.766544,39.726162,39.685776,39.645393,39.605007,39.564625,39.52424,39.483856,39.44347,39.403084,39.3627,39.322315,39.281933,39.241547,39.201164,39.160778,39.120396,39.08001,39.039627,38.99924,38.95886,38.918472,38.87809,38.837704,38.79732,38.756935,37.00817,34.87366,32.73915,30.604641,28.47013,26.33562,24.20111,22.066599,19.93209,17.797579,15.773754,13.758444,11.743133,9.727822,7.712511,5.697201,3.6818895,40.529114,40.488728,40.44834,40.40796,40.367573,40.32719,40.286804,40.24642,40.206036,40.165653,40.125267,40.084885,40.0445,40.004116,39.96373,39.923347,39.88296,39.84258,39.802193,39.76181,39.721424,39.68104,39.640656,39.600273,39.559887,39.519505,39.47912,39.438736,39.39835,39.357967,39.31758,39.2772,39.236813,39.19643,39.156044,39.11566,39.075275,39.034893,38.994507,38.954124,38.91374,38.873356,38.83297,38.792587,38.7522,38.71182,38.671432,38.63105,38.590664,38.550278,38.509895,36.37538,34.24087,32.106358,29.971844,27.837332,25.70282,23.568306,21.433794,19.25245,17.23714,15.221831,13.20652,11.19121,9.1759,7.16059,5.145279,40.282066,40.24168,40.201298,40.16091,40.12053,40.080143,40.03976,39.999374,39.958992,39.918606,39.878223,39.837837,39.79745,39.75707,39.716682,39.6763,39.635914,39.59553,39.555145,39.514763,39.474377,39.433994,39.39361,39.353226,39.31284,39.272457,39.23207,39.19169,39.151302,39.11092,39.070534,39.03015,38.989765,38.949383,38.908997,38.868614,38.828228,38.787846,38.74746,38.707077,38.66669,38.62631,38.585922,38.54554,38.505154,38.464767,38.424385,38.384003,38.343616,38.30323,37.8771,35.742584,33.60807,31.473557,29.339043,27.204529,25.070015,22.935501,20.800985,18.700531,16.68522,14.66991,12.6546,10.63929,8.623979,6.6086693,4.593359,40.075405,40.035023,39.994637,39.954254,39.913868,39.873486,39.8331,39.792717,39.75233,39.71195,39.671562,39.63118,39.590794,39.55041,39.510025,39.46964,39.429256,39.38887,39.348488,39.3081,39.26772,39.227333,39.18695,39.146564,39.106182,39.065796,39.025414,38.985027,38.944645,38.90426,38.863876,38.82349,38.783108,38.74272,38.70234,38.661953,38.62157,38.581184,38.5408,38.500416,38.46003,38.419647,38.37926,38.33888,38.298492,38.25811,38.217724,38.17734,38.136955,38.096573,38.056187,37.244278,35.109768,32.97526,30.840752,28.706242,26.571733,24.437225,22.302717,20.16395,18.148638,16.133326,14.118013,12.102701,10.087389,8.072077,6.0567646,39.82836,39.78798,39.747593,39.70721,39.666824,39.626442,39.586056,39.545673,39.505287,39.464905,39.42452,39.384136,39.34375,39.303368,39.26298,39.2226,39.182213,39.14183,39.101444,39.061058,39.020676,38.98029,38.939907,38.89952,38.85914,38.818752,38.77837,38.737984,38.6976,38.657215,38.616833,38.576447,38.536064,38.495678,38.455296,38.41491,38.374527,38.33414,38.293755,38.253372,38.212986,38.172604,38.132217,38.091835,38.05145,38.011066,37.97068,37.930298,37.88991,37.84953,37.809143,36.61149,34.476974,32.342464,30.207954,28.07344,25.93893,23.80442,21.669909,19.612024,17.596714,15.581402,13.56609,11.550778,9.535466,7.520155,5.5048428,39.621704,39.581318,39.540936,39.50055,39.460167,39.41978,39.3794,39.339012,39.29863,39.258244,39.217857,39.177475,39.13709,39.096706,39.05632,39.015938,38.97555,38.93517,38.894783,38.8544,38.814014,38.773632,38.733246,38.692863,38.652477,38.612095,38.57171,38.531326,38.49094,38.450554,38.41017,38.369785,38.329403,38.289017,38.248634,38.20825,38.167866,38.12748,38.087097,38.04671,38.00633,37.965942,37.92556,37.885174,37.84479,37.804405,37.764023,37.723637,37.68325,37.642868,37.60248,38.113174,35.978664,33.844154,31.709646,29.575138,27.440628,25.30612,23.17161,21.075415,19.060102,17.044792,15.02948,13.014169,10.9988575,8.983546,6.968234,39.374657,39.334274,39.293888,39.253506,39.21312,39.172737,39.13235,39.091965,39.051582,39.011196,38.970814,38.930428,38.890045,38.84966,38.809277,38.76889,38.728508,38.68812,38.64774,38.607353,38.56697,38.526585,38.486202,38.445816,38.405434,38.365047,38.324665,38.28428,38.243896,38.20351,38.163128,38.12274,38.08236,38.041973,38.00159,37.961205,37.920822,37.880436,37.84005,37.799667,37.75928,37.7189,37.678513,37.63813,37.597744,37.55736,37.516975,37.476593,37.436207,37.395824,37.35544,37.315056,35.34587,33.21136,31.076849,28.942337,26.807827,24.673315,22.538803,20.523493,18.50818,16.49287,14.477559,12.462248,10.446938,8.431625,6.416315,39.168,39.127613,39.08723,39.046844,39.006462,38.966076,38.925694,38.885307,38.84492,38.80454,38.764153,38.72377,38.683384,38.643,38.602615,38.562233,38.521847,38.481464,38.44108,38.400696,38.36031,38.319927,38.27954,38.23916,38.198772,38.15839,38.118004,38.07762,38.037235,37.996853,37.956467,37.916084,37.875698,37.83531,37.79493,37.754543,37.71416,37.673775,37.633392,37.593006,37.552624,37.512238,37.471855,37.43147,37.391087,37.3507,37.310318,37.26993,37.22955,37.189163,37.14878,37.108395,36.84756,34.71305,32.57854,30.444033,28.309523,26.175014,24.00219,21.98688,19.97157,17.956259,15.9409485,13.925637,11.910327,9.895017,7.8797054,38.92095,38.88057,38.840183,38.7998,38.759415,38.719032,38.678646,38.638264,38.597878,38.557495,38.51711,38.476727,38.43634,38.395958,38.35557,38.31519,38.274803,38.23442,38.194035,38.153652,38.113266,38.072884,38.032497,37.99211,37.95173,37.911343,37.87096,37.830574,37.79019,37.749805,37.709423,37.669037,37.628654,37.58827,37.547886,37.5075,37.467117,37.42673,37.38635,37.345963,37.30558,37.265194,37.22481,37.184425,37.144043,37.103657,37.063274,37.02289,36.982506,36.94212,36.901733,36.86135,36.21477,34.080257,31.945744,29.811232,27.67672,25.542206,23.450266,21.434956,19.419647,17.404335,15.389027,13.373715,11.358406,9.343096,7.3277855,38.714294,38.67391,38.633526,38.59314,38.552757,38.51237,38.47199,38.431602,38.39122,38.350834,38.31045,38.270065,38.229683,38.189297,38.148914,38.10853,38.068146,38.02776,37.987377,37.94699,37.90661,37.866222,37.825836,37.785454,37.745068,37.704685,37.6643,37.623917,37.58353,37.543148,37.50276,37.46238,37.421993,37.38161,37.341225,37.300842,37.260456,37.220074,37.179688,37.139305,37.09892,37.058537,37.01815,36.977768,36.93738,36.896996,36.856613,36.81623,36.775845,36.73546,36.695076,36.65469,36.614307,35.581978,33.44746,31.312946,29.17843,27.043915,24.913656,22.898346,20.883038,18.867727,16.852417,14.837109,12.821798,10.806489,8.79118,38.47243,38.426865,38.386482,38.346096,38.30571,38.265327,38.22494,38.18456,38.144173,38.10379,38.063404,38.02302,37.982635,37.942253,37.901867,37.861485,37.8211,37.780716,37.74033,37.699947,37.65956,37.61918,37.578793,37.53841,37.498024,37.45764,37.417255,37.376873,37.336487,37.296104,37.25572,37.215336,37.17495,37.134563,37.09418,37.053795,37.013412,36.973026,36.932644,36.892258,36.851875,36.81149,36.771107,36.73072,36.69034,36.649952,36.60957,36.569183,36.5288,36.488415,36.448032,36.407646,36.367264,34.949158,32.81465,30.680145,28.545639,26.41113,24.361763,22.346449,20.331137,18.315825,16.300512,14.285199,12.269887,10.254574,6.7620554,38.536903,38.45162,38.366333,38.281048,38.195763,38.110474,38.018284,37.977898,37.937515,37.89713,37.856747,37.81636,37.775978,37.73559,37.69521,37.654823,37.61444,37.574055,37.53367,37.493286,37.4529,37.412518,37.37213,37.33175,37.291363,37.25098,37.210594,37.17021,37.129826,37.089443,37.049057,37.008675,36.96829,36.927906,36.88752,36.847137,36.80675,36.76637,36.725983,36.6856,36.645214,36.60483,36.564445,36.524063,36.483677,36.443295,36.40291,36.362526,36.32214,36.281757,36.24137,36.20099,36.160603,36.45088,34.316364,32.181854,30.047344,27.912834,25.82515,23.809837,21.794525,19.779215,17.763903,15.7485895,13.733278,11.717966,6.748244,38.51609,38.430805,38.34552,38.260235,38.17495,38.089664,38.00438,37.919094,37.83381,37.748524,37.66324,37.57795,37.52893,37.48855,37.448162,37.40778,37.367393,37.32701,37.286625,37.246243,37.205856,37.165474,37.125088,37.084705,37.04432,37.003937,36.96355,36.92317,36.882782,36.8424,36.802013,36.76163,36.721245,36.680862,36.640476,36.600094,36.559708,36.519325,36.47894,36.438557,36.39817,36.357788,36.3174,36.277016,36.236633,36.196247,36.155865,36.11548,36.075096,36.03471,35.994328,35.95394,35.91356,35.818054,33.683548,31.54904,29.414532,27.28854,25.273228,23.257915,21.242605,19.227293,17.21198,15.19667,11.704154,6.7344337,1.7647133,38.580566,38.49528,38.409996,38.32471,38.239426,38.15414,38.068855,37.98357,37.89828,37.812996,37.72771,37.642426,37.55714,37.471855,37.38657,37.301285,37.216,37.12035,37.079967,37.03958,36.9992,36.958813,36.91843,36.878044,36.83766,36.797276,36.756893,36.716507,36.676125,36.63574,36.595352,36.55497,36.514584,36.4742,36.433815,36.393433,36.353046,36.312664,36.272278,36.231895,36.19151,36.151127,36.11074,36.07036,36.029972,35.98959,35.949203,35.90882,35.868435,35.828053,35.787666,35.747284,35.706898,35.666515,35.185265,33.05075,30.91624,28.751928,26.736616,24.721306,22.705994,20.690683,18.675373,16.66006,11.690336,6.7206116,1.7508879,38.559753,38.47447,38.389183,38.303898,38.218613,38.133327,38.048042,37.962757,37.877472,37.792187,37.7069,37.621616,37.53633,37.451042,37.365757,37.28047,37.195187,37.1099,37.024616,36.93933,36.854046,36.76876,36.683475,36.631004,36.59062,36.550236,36.50985,36.469463,36.42908,36.388695,36.348312,36.307926,36.267544,36.227158,36.186775,36.14639,36.106007,36.06562,36.025238,35.98485,35.94447,35.904083,35.863697,35.823315,35.78293,35.742546,35.70216,35.661777,35.62139,35.58101,35.540623,35.50024,35.459854,35.41947,34.55244,32.417934,30.283426,28.200005,26.184694,24.169386,22.154076,20.138767,16.64625,11.676527,6.7068043,1.7370796,-3.2326431,38.62423,38.538944,38.45366,38.368374,38.28309,38.1978,38.112514,38.02723,37.941944,37.85666,37.771374,37.68609,37.600803,37.51552,37.430233,37.344948,37.259663,37.174377,37.089092,37.003807,36.91852,36.833237,36.747948,36.662663,36.577377,36.492092,36.406807,36.32152,36.22242,36.182037,36.14165,36.10127,36.060883,36.0205,35.980114,35.93973,35.899345,35.858963,35.818577,35.778194,35.73781,35.697422,35.65704,35.616653,35.57627,35.535885,35.495502,35.455116,35.414734,35.374348,35.333965,35.29358,35.253197,35.21281,36.05416,33.919647,31.785133,29.663393,27.648085,25.632774,23.617466,21.602158,16.632435,11.662714,6.692992,1.7232704,-3.2464504,38.60342,38.51813,38.432846,38.34756,38.262276,38.17699,38.091705,38.00642,37.921135,37.83585,37.750565,37.66528,37.579994,37.49471,37.409424,37.324135,37.23885,37.153564,37.06828,36.982994,36.89771,36.812424,36.72714,36.641853,36.55657,36.471283,36.385998,36.300713,36.215424,36.13014,36.044853,35.959568,35.874283,35.788998,35.73307,35.692688,35.6523,35.611916,35.571533,35.531147,35.490765,35.45038,35.409996,35.36961,35.329227,35.28884,35.24846,35.208073,35.16769,35.127304,35.08692,35.046535,35.00615,34.965767,34.92538,33.28685,31.152327,29.111473,27.096165,25.080858,21.588345,16.618624,11.648903,6.679182,1.7094612,-3.2602596,-8.22998,38.667892,38.582607,38.497322,38.412037,38.326748,38.241463,38.156178,38.070892,37.985607,37.900322,37.815037,37.72975,37.644466,37.55918,37.473896,37.38861,37.303326,37.218037,37.13275,37.047466,36.96218,36.876896,36.79161,36.706326,36.62104,36.535755,36.45047,36.365185,36.2799,36.194614,36.10933,36.02404,35.938755,35.85347,35.768185,35.6829,35.597614,35.51233,35.427044,35.32449,35.284103,35.24372,35.203335,35.162952,35.122566,35.082184,35.041798,35.00141,34.96103,34.920643,34.88026,34.839874,34.79949,34.759106,34.718723,34.788548,32.65405,30.574886,28.55957,26.544254,21.574532,16.604807,11.635084,6.6653595,1.6956348,-3.274086,-8.243813,38.647083,38.561794,38.47651,38.391224,38.30594,38.220654,38.13537,38.050083,37.964798,37.879513,37.794228,37.708942,37.623657,37.53837,37.453083,37.367798,37.282513,37.197227,37.111942,37.026657,36.941372,36.856087,36.7708,36.685516,36.600227,36.514942,36.429657,36.34437,36.259087,36.1738,36.088516,36.00323,35.917946,35.83266,35.747375,35.66209,35.576805,35.491516,35.40623,35.320946,35.23566,35.150375,35.06509,34.979805,34.89452,34.835136,34.794754,34.754368,34.713985,34.6736,34.633217,34.59283,34.55245,34.512062,34.47168,34.155758,32.038277,30.02296,26.53044,21.560719,16.590994,11.621273,6.6515484,1.6818275,-3.2878952,-8.257618,-13.227341,38.71155,38.626266,38.54098,38.455696,38.37041,38.285126,38.19984,38.114555,38.02927,37.943985,37.8587,37.773415,37.68813,37.602844,37.517555,37.43227,37.346985,37.2617,37.176414,37.09113,37.005844,36.92056,36.835274,36.74999,36.664703,36.57942,36.494133,36.408844,36.32356,36.238274,36.15299,36.067703,35.982418,35.897133,35.811848,35.726563,35.641277,35.555992,35.470707,35.38542,35.300137,35.21485,35.129562,35.044277,34.958992,34.873707,34.78842,34.703136,34.61785,34.532566,34.426556,34.386173,34.345787,34.305405,34.26502,34.224632,33.501667,31.486351,26.51663,21.54691,16.577187,11.607466,6.637745,1.6680222,-3.3017006,-8.27142,-13.241142,38.690742,38.605457,38.52017,38.434883,38.349598,38.264313,38.179028,38.093742,38.008457,37.923172,37.837887,37.7526,37.667316,37.58203,37.496746,37.41146,37.32617,37.240887,37.1556,37.070316,36.98503,36.899746,36.81446,36.729176,36.64389,36.558605,36.47332,36.388035,36.30275,36.21746,36.132175,36.04689,35.961605,35.87632,35.791035,35.70575,35.620464,35.53518,35.449894,35.36461,35.279324,35.19404,35.10875,35.023464,34.93818,34.852894,34.76761,34.682323,34.59704,34.511753,34.426468,34.341183,34.255898,34.170612,34.085327,34.00004,31.472536,26.502811,21.533087,16.563364,11.593637,6.6239166,1.6541901,-3.3155327,-8.285259,-13.254982,-18.224705,38.75522,38.66993,38.584644,38.49936,38.414074,38.32879,38.243504,38.15822,38.072933,37.987648,37.902363,37.817078,37.731792,37.646507,37.56122,37.475933,37.390648,37.305363,37.220078,37.134792,37.049507,36.964222,36.878937,36.79365,36.708366,36.62308,36.537796,36.452507,36.36722,36.281937,36.19665,36.111366,36.02608,35.940796,35.85551,35.770226,35.68494,35.599655,35.51437,35.429085,35.343796,35.25851,35.173225,35.08794,35.002655,34.91737,34.832085,34.7468,34.661514,34.57623,34.490944,34.40566,34.320374,34.235085,34.1498,34.064514,29.286606,25.205473,21.51927,16.549547,11.579824,6.6101007,1.640379,-3.3293457,-8.29907,-13.268791,-18.238514,38.734406,38.64912,38.563835,38.478546,38.39326,38.307976,38.22269,38.137405,38.05212,37.966835,37.88155,37.796265,37.71098,37.625694,37.54041,37.45512,37.369835,37.28455,37.199265,37.11398,37.028694,36.94341,36.858124,36.77284,36.687553,36.60227,36.516983,36.431694,36.34641,36.261124,36.17584,36.090553,36.00527,35.919983,35.834698,35.749413,35.664127,35.578842,35.493553,35.408268,35.322983,35.237698,35.152412,35.067127,34.981842,34.896557,34.81127,34.725986,34.6407,34.555416,34.47013,34.384842,34.299557,34.21427,34.128986,30.388481,22.575193,18.494074,14.412954,10.331835,6.2507153,1.626559,-3.3431616,-8.312883,-13.282604,-18.252327,-23.222048,39.95767,38.713593,38.628304,38.54302,38.457733,38.372448,38.287163,38.201878,38.116592,38.031307,37.946022,37.860737,37.77545,37.690166,37.60488,37.519596,37.43431,37.349022,37.263737,37.17845,37.093166,37.00788,36.922596,36.83731,36.752026,36.66674,36.581455,36.49617,36.410885,36.3256,36.240314,36.15503,36.06974,35.984455,35.89917,35.813885,35.7286,35.643314,35.55803,35.472744,35.38746,35.302174,35.21689,35.131603,35.046318,34.961033,34.875748,34.79046,34.705177,34.61989,34.534603,34.449318,34.364033,34.278748,34.193462,31.883286,19.944958,15.863836,11.782712,7.7015896,3.6204662,-0.46065903,-4.5417805,-8.32671,-13.296429,-18.266148,-23.235867,40.98701,38.946255,38.607494,38.52221,38.436924,38.35164,38.266354,38.18107,38.09578,38.010494,37.92521,37.839924,37.75464,37.669353,37.58407,37.498783,37.413498,37.328213,37.242928,37.157642,37.072357,36.98707,36.901783,36.816498,36.731213,36.645927,36.560642,36.475357,36.39007,36.304787,36.2195,36.134216,36.048927,35.963642,35.878357,35.79307,35.707787,35.6225,35.537216,35.45193,35.366646,35.28136,35.196075,35.11079,35.025505,34.940216,34.85493,34.769646,34.68436,34.599075,34.51379,34.428505,34.34322,34.257935,33.37805,20.26108,13.233546,9.152427,5.071307,0.99018764,-3.0909328,-7.1720505,-11.253168,-15.33429,-19.415407,-23.49653,-28.21942,44.057144,42.016388,39.975628,38.586685,38.5014,38.416115,38.33083,38.24554,38.160255,38.07497,37.989685,37.9044,37.819115,37.73383,37.648544,37.56326,37.477974,37.39269,37.307404,37.222115,37.13683,37.051544,36.96626,36.880974,36.79569,36.710403,36.62512,36.539833,36.454548,36.369263,36.283978,36.198692,36.113403,36.02812,35.942833,35.857548,35.772263,35.686977,35.601692,35.516407,35.43112,35.345837,35.26055,35.175262,35.089977,35.004692,34.919407,34.83412,34.748837,34.66355,34.578266,34.49298,34.407696,34.32241,34.872837,21.75592,10.6033125,6.5221963,2.44108,-1.6400366,-5.7211514,-9.802267,-13.883385,-17.964502,-22.045618,-26.126734,-30.20785,45.086483,43.045723,41.004967,38.96421,38.480587,38.3953,38.310017,38.22473,38.139446,38.05416,37.968876,37.88359,37.798306,37.71302,37.62773,37.542446,37.45716,37.371876,37.28659,37.201305,37.11602,37.030735,36.94545,36.860165,36.77488,36.689594,36.60431,36.51902,36.433735,36.34845,36.263165,36.17788,36.092594,36.00731,35.922024,35.83674,35.751453,35.66617,35.580883,35.495598,35.41031,35.325024,35.23974,35.154453,35.069168,34.983883,34.898598,34.813313,34.728027,34.642742,34.557457,34.47217,34.386887,34.301598,23.250732,10.133852,3.8919613,-0.18915796,-4.270276,-8.351396,-12.432516,-16.513634,-20.594753,-24.675873,-28.756992,-32.838108,-36.919228,48.156586,46.11583,44.07507,42.034313,39.993553,38.459778,38.374493,38.289204,38.20392,38.118633,38.033348,37.948063,37.862778,37.777493,37.692207,37.606922,37.521637,37.43635,37.351063,37.265778,37.180492,37.095207,37.009922,36.924637,36.83935,36.754066,36.66878,36.583496,36.49821,36.412926,36.327637,36.24235,36.157066,36.07178,35.986496,35.90121,35.815926,35.73064,35.645355,35.56007,35.474785,35.389496,35.30421,35.218925,35.13364,35.048355,34.96307,34.877785,34.7925,34.707214,34.62193,34.536644,34.451355,37.8624,24.745468,11.628534,1.2616678,-2.819449,-6.900566,-10.981683,-15.062801,-19.143917,-23.225035,-27.306152,-31.387266,-35.468384,-39.5495,49.185932,47.145172,45.104416,43.063656,41.022892,38.982132,38.353676,38.26839,38.183105,38.09782,38.012535,37.92725,37.841965,37.75668,37.671394,37.58611,37.50082,37.415535,37.33025,37.244965,37.15968,37.074394,36.98911,36.903824,36.81854,36.733253,36.64797,36.562683,36.477398,36.392113,36.306828,36.221542,36.136253,36.05097,35.965683,35.880398,35.795113,35.709827,35.624542,35.539257,35.45397,35.368687,35.2834,35.198116,35.11283,35.027546,34.94226,34.85697,34.771687,34.6864,34.601116,34.51583,34.430546,26.240269,13.123367,6.462097e-3,-5.449684,-9.530803,-13.611922,-17.69304,-21.774162,-25.85528,-29.936398,-34.017517,-38.098637,-42.17976,-46.260876,52.256042,50.21529,48.17453,46.133778,44.09302,42.052265,40.01151,38.332867,38.24758,38.162296,38.07701,37.991726,37.906437,37.82115,37.735867,37.65058,37.565296,37.48001,37.394726,37.30944,37.224155,37.13887,37.053585,36.9683,36.88301,36.797726,36.71244,36.627155,36.54187,36.456585,36.3713,36.286015,36.20073,36.115444,36.03016,35.94487,35.859585,35.7743,35.689014,35.60373,35.518444,35.43316,35.347874,35.26259,35.177303,35.09202,35.00673,34.921444,34.83616,34.750874,34.66559,34.580303,40.851967,27.735023,14.618082,1.5011406,-8.079979,-12.161097,-16.242214,-20.323332,-24.40445,-28.485567,-32.56669,-36.647804,-40.72892,-44.81004,-48.891155,53.285397,51.24464,49.20388,47.163124,45.122364,43.081608,41.04085,39.000095,38.22677,38.141483,38.0562,37.970913,37.885628,37.800343,37.715057,37.629772,37.544487,37.4592,37.373913,37.288628,37.203342,37.118057,37.032772,36.947487,36.8622,36.776917,36.69163,36.606346,36.52106,36.435776,36.35049,36.2652,36.179916,36.09463,36.009346,35.92406,35.838776,35.75349,35.668205,35.58292,35.497635,35.41235,35.327065,35.241776,35.15649,35.071205,34.98592,34.900635,34.81535,34.730064,34.64478,34.559494,29.229818,16.112902,2.995985,-10.120934,-14.79133,-18.872448,-22.953566,-27.034681,-31.115799,-35.196915,-39.278034,-43.35915,-47.44027,-51.521385,-55.602505,56.355488,54.31473,52.273975,50.23322,48.192463,46.151703,44.110947,42.07019,40.029434,38.20596,38.120674,38.03539,37.950104,37.86482,37.77953,37.694244,37.60896,37.523674,37.43839,37.353104,37.26782,37.182533,37.097248,37.011963,36.926678,36.841393,36.756107,36.67082,36.585533,36.500248,36.414963,36.329678,36.244392,36.159107,36.073822,35.988537,35.90325,35.817966,35.73268,35.647392,35.56211,35.47682,35.391537,35.30625,35.220966,35.13568,35.050396,34.96511,34.879826,34.79454,34.709255,34.62397,30.724606,17.60771,4.4908123,-8.62608,-17.421564,-21.502686,-25.583805,-29.664927,-33.746048,-37.82717,-41.90829,-45.989414,-50.070534,-54.151653,-58.232777,57.384857,55.3441,53.303345,51.262585,49.22183,47.181072,45.140316,43.09956,41.058804,39.018047,38.09986,38.014572,37.929287,37.844,37.758717,37.67343,37.588146,37.50286,37.417576,37.33229,37.247005,37.16172,37.076435,36.99115,36.90586,36.820576,36.73529,36.650005,36.56472,36.479435,36.39415,36.308865,36.22358,36.138294,36.05301,35.967724,35.88244,35.79715,35.711864,35.62658,35.541294,35.45601,35.370724,35.28544,35.200153,35.11487,35.029583,34.944298,34.859013,34.773727,34.68844,32.219376,19.102448,5.985523,-7.131405,-20.051859,-24.132977,-28.214096,-32.29521,-36.376328,-40.45745,-44.538567,-48.619682,-52.700806,-56.78192,-60.86304,-64.94415]
+ examples/rasterize/rasterize-test2.txt view
@@ -0,0 +1,4 @@+[((-309,-170),-11.445068),((-397,-258),39.884766),((-280,-273),39.814148),((-324,-236),79.39956),((-349,-182),59.562397),((-375,-221),54.81807),((-410,-194),75.88132),((-383,-188),48.284355),((-404,-225),37.207848),((-316,-199),29.185278),((-305,-213),43.06239),((-362,-201),56.988422),((-374,-256),158.54184),((-350,-246),84.5153),((-335,-252),121.0145),((-342,-262),371.26556),((-361,-258),461.29483),((-371,-267),346.42474),((-363,-251),221.5157),((-367,-241),134.81987),((-353,-260),441.5962),((-332,-271),140.75253),((-318,-277),66.3733)]+[(6,8,7),(8,5,7),(8,19,5),(12,17,16),(19,12,18),(12,16,18),(18,16,20),(11,13,3),(3,9,11),(3,10,9),(2,10,3),(3,22,2),(14,15,21),(22,14,21),(3,14,22),(13,14,3),(15,14,13),(20,15,13),(18,20,13),(19,18,13),(5,19,13),(11,5,13),(7,5,11),(7,11,4),(11,9,4),(9,0,4),(17,12,1),(19,1,12),(8,1,19)]+((-385,-257),(-319,-191))+[99.89475,95.73703,91.57931,87.421585,83.26386,79.10614,78.22758,78.754395,79.28121,79.80802,80.33484,80.86166,81.38847,81.91528,82.4421,82.96892,83.49573,84.022545,84.54936,85.07618,85.60299,86.12981,86.656624,87.18344,84.782684,81.22195,77.66122,74.10048,70.53975,66.97902,63.41828,59.85755,56.296814,52.736084,49.17535,48.702374,48.653236,48.6041,48.554962,48.50583,48.45669,48.407555,48.358418,48.30928,48.260147,48.21101,48.161873,48.112736,48.0636,48.01446,47.96533,47.91619,47.867054,47.817917,47.76878,47.719646,47.67051,47.621372,47.572235,47.523098,47.47396,47.424828,47.37569,47.326553,47.277416,47.253407,48.259827,107.4941,103.33639,99.17867,95.020966,90.86325,86.705536,80.83015,81.356964,81.88378,82.41059,82.93741,83.464226,83.991035,84.51785,85.04467,85.57149,86.0983,86.625114,87.15193,87.67874,88.20556,88.732376,89.259186,91.22216,87.66142,84.10069,80.539955,76.97922,73.41849,69.85775,66.29702,62.736282,59.17555,55.61481,52.054077,49.34097,49.291832,49.242695,49.193558,49.144424,49.095287,49.04615,48.997013,48.947876,48.898743,48.849606,48.80047,48.75133,48.702194,48.65306,48.603924,48.554787,48.50565,48.456512,48.407375,48.358242,48.309105,48.259968,48.21083,48.161694,48.11256,48.063423,48.014286,47.96515,47.91601,47.866875,47.81774,110.935745,106.77804,102.62032,98.462616,94.30491,90.1472,85.98949,84.48634,85.01315,85.53997,86.06679,86.593605,87.12042,87.64723,88.17405,88.70087,89.227684,89.7545,90.28131,90.80813,91.334946,91.86176,92.38858,90.54018,86.97944,83.4187,79.85796,76.297226,72.736496,69.17575,65.61502,62.054283,58.49354,54.932804,51.372066,49.930424,49.881287,49.83215,49.783016,49.73388,49.684742,49.635605,49.586468,49.537334,49.488197,49.43906,49.389923,49.340786,49.291653,49.242516,49.19338,49.14424,49.095104,49.045967,48.996834,48.947697,48.89856,48.849422,48.800285,48.751152,48.702015,48.652878,48.60374,48.554604,48.50547,48.456333,48.407196,118.535225,114.3775,110.21978,106.06206,101.90434,97.74662,93.5889,87.08891,87.61572,88.14254,88.66936,89.196175,89.72299,90.24981,90.77662,91.30344,91.83025,92.35707,92.88389,93.410706,93.937515,94.46433,96.97967,93.41893,89.8582,86.29746,82.736725,79.175995,75.61526,72.05453,68.49379,64.93306,61.372322,57.811584,54.250854,50.56902,50.519882,50.47075,50.42161,50.372475,50.323338,50.2742,50.225067,50.17593,50.126793,50.077656,50.02852,49.97938,49.93025,49.88111,49.831974,49.782837,49.7337,49.684566,49.63543,49.586292,49.537155,49.488018,49.438885,49.389748,49.34061,49.291473,49.242336,49.193203,49.144066,49.08673,48.972,121.97686,117.819145,113.66143,109.503716,105.346,101.188286,97.03057,92.872856,90.74511,91.27193,91.798744,92.325554,92.85237,93.37919,93.906,94.432816,94.95963,95.48645,96.01326,96.54008,97.066895,97.59371,96.29767,92.73693,89.1762,85.61546,82.054726,78.49399,74.93326,71.37252,67.81178,64.25105,60.690315,57.12958,53.568848,51.158478,51.109344,51.060207,51.01107,50.961933,50.912796,50.863663,50.814526,50.76539,50.71625,50.667114,50.61798,50.568844,50.519707,50.47057,50.421432,50.372295,50.323162,50.274025,50.224888,50.17575,50.126614,50.07748,50.028343,49.979206,49.93007,49.831738,49.71701,49.60228,49.487553,49.37282,49.25809,129.57634,125.41862,121.260895,117.103165,112.94544,108.78772,104.62999,100.47226,96.31454,93.87449,94.401306,94.928116,95.45493,95.98175,96.50857,97.03538,97.562195,98.08901,98.61583,99.14265,99.66946,100.19627,99.176476,95.61574,92.055,88.49426,84.933525,81.37279,77.81205,74.25131,70.690575,67.12984,63.569103,60.008366,56.447628,51.797073,51.747936,51.6988,51.649662,51.600525,51.551388,51.502254,51.453117,51.40398,51.354843,51.305706,51.256573,51.207436,51.1583,51.10916,51.060024,51.01089,50.961754,50.912617,50.86348,50.814342,50.765205,50.691475,50.576744,50.462017,50.347286,50.23256,50.11783,50.003098,49.88837,49.77364,49.658913,133.7453,128.86026,124.70254,120.544815,116.3871,112.22938,108.071655,103.91394,99.75621,97.00387,97.530685,98.0575,98.58432,99.11113,99.63795,100.164764,100.69158,101.21839,101.74521,102.272026,102.79884,102.05522,98.494484,94.93375,91.373,87.81226,84.251526,80.69079,77.13005,73.56931,70.008575,66.44784,62.8871,59.32636,55.765625,52.38653,52.337395,52.288258,52.23912,52.189983,52.14085,52.091713,52.042576,51.99344,51.9443,51.89517,51.84603,51.796894,51.747757,51.69862,51.649487,51.60035,51.551212,51.43648,51.321754,51.207024,51.092297,50.977566,50.86284,50.748108,50.633377,50.51865,50.40392,50.289192,50.17446,50.05973,49.945004,147.89052,136.45961,132.3019,128.14418,123.986465,119.82875,115.671036,111.51332,107.355606,103.19789,100.133255,100.66007,101.18689,101.7137,102.24052,102.767334,103.29414,103.82096,104.34778,104.87459,105.401405,104.93397,101.37323,97.81249,94.251755,90.691025,87.13029,83.56955,80.00882,76.44808,72.887344,69.326614,65.76588,62.20514,58.644405,55.083668,52.97599,52.926853,52.877716,52.828583,52.779446,52.73031,52.68117,52.632034,52.5829,52.533764,52.484627,52.43549,52.41095,52.296223,52.18149,52.066765,51.952034,51.837303,51.722576,51.607845,51.49312,51.378387,51.263657,51.14893,51.0342,50.919468,50.80474,50.69001,50.575283,50.460552,50.34684,146.72606,139.90137,135.74365,131.58592,127.4282,123.27048,119.112755,114.95503,110.7973,106.63959,103.26264,103.78945,104.31627,104.84309,105.369896,105.89671,106.42353,106.95034,107.47716,108.003975,107.812706,104.251976,100.69124,97.1305,93.56976,90.009026,86.44829,82.88756,79.32681,75.76608,72.205345,68.64461,65.08387,61.523132,57.9624,54.401657,53.565445,53.516308,53.467175,53.418037,53.3689,53.319763,53.270626,53.221493,53.155956,53.04123,52.9265,52.81177,52.69704,52.582314,52.467583,52.352856,52.238125,52.123398,52.008667,51.89394,51.77921,51.664482,51.54975,51.43502,51.320293,51.205563,51.090836,50.976105,50.861378,50.748936,50.64489,160.87128,147.50072,143.343,139.18529,135.02757,130.86986,126.712135,122.55441,118.3967,114.23898,110.08126,106.39202,106.91884,107.445656,107.97247,108.49928,109.0261,109.55292,110.079735,110.606544,110.69146,107.13073,103.56999,100.00926,96.448524,92.88779,89.32706,85.76632,82.20559,78.64485,75.08412,71.523384,67.96265,64.40192,60.84118,57.28045,54.204044,54.154907,54.10577,54.056633,54.015694,53.900967,53.786236,53.67151,53.556778,53.44205,53.32732,53.212593,53.097862,52.983135,52.868404,52.753677,52.638947,52.524216,52.40949,52.294758,52.18003,52.0653,51.950573,51.835842,51.721115,51.606384,51.491657,51.376926,51.2622,51.151028,51.04698,159.70679,150.94249,146.78476,142.62703,138.4693,134.31158,130.15385,125.996124,121.838394,117.68067,113.52295,109.5214,110.04822,110.575035,111.101845,111.62866,112.15547,112.68229,113.20911,113.5702,110.00947,106.44873,102.88799,99.327255,95.766525,92.20579,88.64505,85.08432,81.52358,77.962845,74.402115,70.841385,67.28064,63.719906,60.159172,56.59844,54.760704,54.645977,54.531246,54.41652,54.30179,54.187057,54.07233,53.9576,53.842873,53.72814,53.613415,53.498684,53.383953,53.269226,53.154495,53.03977,52.925037,52.81031,52.69558,52.580853,52.46612,52.35139,52.236664,52.121933,52.007206,51.892475,51.77775,51.663017,51.55312,51.44907,51.345024,173.852,158.54184,154.38412,150.22641,146.0687,141.91098,137.75327,133.59555,129.43784,125.280106,121.12239,116.964676,112.65078,113.1776,113.704414,114.231224,114.75804,115.28486,115.811676,116.44895,112.888214,109.327484,105.76675,102.20601,98.64528,95.08454,91.52381,87.96307,84.402336,80.841606,77.28087,73.72014,70.1594,67.755745,61.88085,56.00596,55.60377,55.201584,54.932068,54.81734,54.70261,54.587883,54.473152,54.35842,54.243694,54.128963,54.014236,53.899506,53.78478,53.670048,53.55532,53.44059,53.325863,53.211132,53.0964,52.981674,52.866943,52.752216,52.637486,52.52276,52.408028,52.2933,52.17857,52.059265,51.955215,51.851166,51.74712,185.70709,164.02136,158.6232,153.66808,149.51036,145.35265,141.19493,137.03722,132.8795,128.72179,124.56407,120.40636,116.24864,116.30698,116.83379,117.36061,117.88743,118.414246,118.941055,115.76696,112.20623,108.64549,105.08476,101.524025,97.963295,94.40256,90.84183,87.28109,83.72035,80.15962,76.59889,71.88107,66.00618,60.131294,56.992752,56.590565,56.188377,55.78619,55.384,55.10343,54.9887,54.873974,54.759243,54.644512,54.529785,54.415054,54.300327,54.185596,54.07087,53.95614,53.84141,53.72668,53.611954,53.497223,53.382492,53.267765,53.153034,53.038307,52.923576,52.80885,52.69412,52.57939,52.46466,52.357307,52.253258,52.149208,52.045162,212.87228,196.23668,169.50089,164.10275,158.70462,152.95207,148.79436,144.63664,140.47893,136.3212,132.16348,128.00577,123.848045,118.909546,119.43636,119.96318,120.49,121.016815,122.20645,118.64571,115.084984,111.52425,107.96352,104.40278,100.84204,97.28131,93.72058,90.15984,86.599106,81.881294,76.00641,70.131516,64.25663,58.381737,57.97955,57.577362,57.175175,56.772984,56.370796,55.96861,55.56642,55.274796,55.160065,55.045334,54.930607,54.815876,54.70115,54.58642,54.47169,54.35696,54.24223,54.127502,54.01277,53.898045,53.783314,53.668587,53.553856,53.439125,53.324398,53.209667,53.09494,52.98021,52.863445,52.7594,52.65535,52.5513,52.447254,228.83853,200.64885,174.9804,169.58226,164.18411,158.78598,153.38785,148.07831,143.9206,139.76288,135.60516,131.44745,127.28972,123.132,122.56575,123.09256,123.61938,124.146194,121.52451,117.963776,114.40303,110.84229,107.281555,103.72082,100.16008,96.599335,91.88152,86.00664,80.131744,74.25685,68.381966,62.50707,59.36853,58.966343,58.564156,58.16197,57.759777,57.35759,56.955402,56.553215,56.151024,55.748837,55.446156,55.331425,55.216698,55.101967,54.98724,54.87251,54.757782,54.64305,54.52832,54.413593,54.298862,54.184135,54.069405,53.954678,53.839947,53.725216,53.61049,53.495758,53.38103,53.2663,53.16149,53.05744,52.953392,52.849346,52.745296,262.8001,233.93083,205.06157,180.45992,175.06177,169.66364,164.26549,158.86736,153.46921,148.07108,143.20454,139.04683,134.88911,130.7314,125.16832,125.69513,126.22195,127.964,124.40326,120.84252,117.281784,113.72105,110.16031,107.756645,101.88175,96.00686,90.13197,84.25708,78.38219,72.50729,66.63241,60.757515,60.355328,59.95314,59.55095,59.14876,58.746574,58.344387,57.9422,57.54001,57.13782,56.735634,56.333447,55.93126,55.61752,55.50279,55.38806,55.27333,55.158604,55.043873,54.929146,54.814415,54.699688,54.584957,54.47023,54.3555,54.24077,54.12604,54.01131,53.896584,53.781853,53.667633,53.563583,53.459538,53.355488,53.25144,53.147392,267.21292,238.34358,209.47424,185.93944,180.54129,175.14314,169.74501,164.34686,158.94872,153.55057,148.15244,142.75429,138.33078,134.17307,130.01537,128.82451,129.35133,127.28201,123.72127,120.16053,116.59979,111.88197,106.00708,100.132195,94.2573,88.382416,82.50752,76.63263,70.75774,64.88285,61.74431,61.34212,60.939934,60.537746,60.13556,59.73337,59.331184,58.928993,58.526806,58.12462,57.72243,57.320244,56.918056,56.51587,56.113678,55.788883,55.674152,55.559425,55.444695,55.329967,55.215237,55.100506,54.98578,54.871048,54.75632,54.64159,54.526863,54.412132,54.2974,54.182674,54.069725,53.965675,53.86163,53.75758,53.65353,53.549484,53.445435,300.49503,271.62576,242.75652,213.88724,191.41904,186.02089,180.62274,175.22461,169.82646,164.42831,159.03017,153.63202,148.23387,142.83572,137.61478,131.42708,133.72148,130.16075,126.60001,121.882195,116.00731,110.132416,104.25752,98.38264,92.507744,86.63286,80.757965,74.88307,69.00818,63.133293,62.731106,62.32892,61.926727,61.52454,61.122353,60.720165,60.317978,59.915787,59.5136,59.111412,58.709225,58.307037,57.904846,57.50266,57.10047,56.698284,56.296093,55.960243,55.845516,55.730785,55.61606,55.501328,55.386597,55.27187,55.15714,55.04241,54.92768,54.812954,54.698223,54.583492,54.471817,54.367767,54.26372,54.15967,54.055622,53.951576,53.847527,304.9071,276.03796,247.16887,218.29976,196.89856,191.50041,186.10226,180.70412,175.30597,169.90782,164.50967,159.11153,153.71338,148.31523,142.91708,137.51895,131.88243,126.00754,120.132645,114.25775,108.382866,102.507965,96.63309,90.758194,84.8833,79.00841,73.133514,67.25863,64.12009,63.7179,63.315712,62.913525,62.511337,62.10915,61.70696,61.30477,60.902584,60.500397,60.09821,59.696022,59.29383,58.891644,58.489456,58.08727,57.68508,57.28289,56.880703,56.478516,56.131607,56.01688,55.90215,55.787422,55.67269,55.557964,55.443233,55.328506,55.213776,55.09905,54.984318,54.873913,54.769863,54.665817,54.561768,54.457718,54.35367,54.249622,54.145573,338.18912,309.31995,280.45078,251.5816,222.71242,202.37807,196.97992,191.58177,186.18362,180.78549,175.38734,169.9892,164.59105,162.07732,150.91035,139.7434,130.13289,124.258,118.38311,112.50822,106.63332,100.75843,94.88354,89.008644,83.13375,77.25885,71.383965,65.50907,65.10688,64.7047,64.302505,63.90032,63.49813,63.095943,62.693756,62.29157,61.88938,61.48719,61.085003,60.682816,60.28063,59.87844,59.476254,59.074066,58.671875,58.269688,57.8675,57.465313,57.063126,56.66094,56.30297,56.188244,56.073513,55.958786,55.844055,55.729324,55.614597,55.499866,55.380054,55.276005,55.171955,55.06791,54.96386,54.85981,54.755764,54.651714,54.54767,342.602,313.73276,284.86353,255.99431,227.12508,207.8576,202.45946,197.06131,191.66315,186.26501,180.86685,172.58429,161.41728,150.25029,139.0833,128.38329,122.50839,116.6335,110.75861,104.88373,99.00884,93.13396,87.25906,81.38418,75.50929,69.6344,66.495865,66.09368,65.69149,65.2893,64.887115,64.484924,64.08274,63.68055,63.278362,62.876175,62.473984,62.071796,61.66961,61.26742,60.865234,60.463043,60.060856,59.65867,59.25648,58.854294,58.452103,58.049915,57.647728,57.24554,56.843353,56.474335,56.359604,56.244877,56.130146,56.015415,55.90069,55.785957,55.678097,55.574047,55.47,55.36595,55.2619,55.157856,55.053806,54.94976,54.84571,375.88403,347.01477,318.1455,289.27625,260.40698,231.5377,213.33711,207.93896,202.5408,194.25824,183.09126,171.92427,160.7573,149.5903,138.42331,126.63374,120.75885,114.883965,109.00907,103.134186,97.25929,91.38441,85.50952,79.63463,73.759735,67.88485,67.48266,67.080475,66.67828,66.2761,65.87391,65.471725,65.069534,64.66734,64.26516,63.86297,63.46078,63.058594,62.656406,62.25422,61.852028,61.44984,61.047653,60.645466,60.24328,59.84109,59.438904,59.036713,58.634525,58.232338,57.83015,57.427963,57.025772,56.6457,56.530968,56.416237,56.30151,56.184235,56.08019,55.97614,55.872093,55.768044,55.663994,55.559948,55.4559,55.351852,55.247803,380.2961,351.42694,322.55777,293.6886,264.81946,235.95029,215.9322,204.76523,193.59825,182.43127,171.26428,160.09732,148.93033,137.76335,126.596375,119.00932,113.13443,107.25954,101.38464,95.50975,89.63486,83.75997,77.88508,72.010185,68.87164,68.46946,68.06727,67.66508,67.26289,66.8607,66.45852,66.05633,65.65414,65.25195,64.84976,64.44758,64.04539,63.6432,63.241013,62.83882,62.436634,62.034447,61.63226,61.230072,60.82788,60.425694,60.023506,59.62132,59.21913,58.81694,58.414753,58.012566,57.61038,57.20819,56.81706,56.70233,56.5876,56.482285,56.378235,56.274185,56.17014,56.06609,55.962044,55.857994,55.753944,55.6499,55.54585,413.5782,384.709,355.83984,322.58194,284.9353,246.05748,215.27217,204.1052,192.93823,181.77126,170.60428,159.43732,148.27036,137.1034,125.93641,117.25979,111.384895,105.51,99.6351,93.76021,87.885315,82.01042,76.13553,70.26063,69.85844,69.45625,69.05406,68.65188,68.24969,67.847496,67.44531,67.04312,66.64094,66.23875,65.83656,65.43437,65.03218,64.63,64.227806,63.82562,63.42343,63.021244,62.619057,62.216866,61.81468,61.41249,61.010303,60.608116,60.205925,59.803738,59.40155,58.999363,58.597176,58.194984,57.7928,57.39061,56.988422,56.884373,56.780327,56.676277,56.57223,56.46818,56.364132,56.260086,56.156036,56.05199,55.94794,404.8247,367.17792,329.5312,291.8844,257.93103,232.59538,207.25974,192.27818,181.1112,169.94421,158.77724,147.61026,136.44327,125.27629,115.51018,109.63529,103.7604,97.88551,92.01063,86.135735,80.26085,74.385956,71.24742,70.84524,70.44305,70.040855,69.63867,69.23648,68.8343,68.432106,68.02992,67.62773,67.22554,66.82336,66.421165,66.01898,65.61679,65.2146,64.812416,64.410225,64.00804,63.60585,63.203663,62.801476,62.399284,61.9971,61.59491,61.192722,60.790535,60.388348,59.98616,59.58397,59.131733,58.52934,57.926945,57.056885,56.642334,57.18242,57.07837,56.974323,56.870274,56.766224,56.662178,56.55813,56.454082,56.350033,56.245983,411.7741,374.12738,336.48068,295.14066,269.80493,244.46924,219.13354,191.61813,180.45117,169.2842,158.11723,146.95026,135.7833,124.616325,113.76065,107.88576,102.010864,96.13597,90.26108,84.38619,78.5113,72.636406,72.234215,71.83203,71.42984,71.02766,70.625465,70.223274,69.82109,69.4189,69.016716,68.614525,68.21233,67.81015,67.40796,67.005775,66.603584,66.20139,65.79921,65.39702,64.994835,64.59264,64.19045,63.78827,63.386078,62.98389,62.581703,62.179516,61.77733,61.275036,60.672646,60.07025,59.467857,58.865467,58.36345,57.12535,55.730385,56.296238,56.86209,57.376415,57.272366,57.16832,57.06427,56.960224,56.856174,56.752125,56.64808,381.0766,343.4298,307.0142,281.67862,256.34305,231.00748,205.6719,180.33632,168.62431,157.45732,146.29034,135.12335,123.956375,112.78939,106.136215,100.26132,94.38643,88.511536,82.636635,76.76174,73.6232,73.221016,72.818825,72.41663,72.01445,71.61226,71.210075,70.807884,70.40569,70.00351,69.60132,69.199135,68.79694,68.39476,67.99257,67.59038,67.188194,66.786,66.38381,65.98163,65.57944,65.17725,64.77506,64.37288,63.970688,63.418346,62.815952,62.21356,61.611164,61.008774,60.40638,59.803986,59.20159,58.43191,57.193813,55.95571,55.384296,55.95015,56.516003,57.081856,57.57041,57.466362,57.362316,57.258266,57.154217,57.05017,56.94612,388.02606,344.22375,318.88812,293.55252,268.21692,242.88129,217.54567,192.21005,167.96428,156.79727,145.63028,134.46327,123.29627,110.26149,104.386604,98.51172,92.63684,86.761955,80.88707,75.012184,74.60999,74.20781,73.80562,73.403435,73.00124,72.59905,72.19687,71.79468,71.392494,70.9903,70.58812,70.18593,69.78374,69.38155,68.97936,68.57718,68.17499,67.7728,67.37061,66.96842,66.56624,66.16405,65.56165,64.95926,64.356865,63.754475,63.15208,62.549686,61.947296,61.344902,60.742508,60.140114,59.738476,58.500378,57.26228,56.024185,54.472347,55.0382,55.604053,56.169907,56.73576,57.301613,57.76441,57.66036,57.556313,57.452263,57.348213,357.3289,330.76205,305.42642,280.09076,254.75513,229.41948,204.08383,178.74818,156.13725,144.97028,133.80328,122.63629,111.469315,102.63708,96.762184,90.8873,85.012405,79.13751,75.99898,75.596794,75.1946,74.79241,74.39023,73.98804,73.58585,73.18366,72.78148,72.37929,71.9771,71.57491,71.17272,70.77054,70.36835,69.966156,69.56397,69.16178,68.7596,68.30736,67.70496,67.10257,66.500175,65.89778,65.29539,64.69299,64.0906,63.488205,62.88581,62.283417,61.681023,61.07863,60.476234,59.806923,58.568825,57.33073,56.092636,54.85454,54.12626,54.692112,55.257965,55.82382,56.38967,56.955524,57.521378,57.958405,57.854355,57.75031,57.64626,367.97165,342.636,317.30032,291.96466,266.62897,241.2933,215.95764,190.62196,165.2863,144.31024,133.14328,121.9763,110.80934,100.88754,95.01265,89.13776,83.26286,77.38796,76.98577,76.58359,76.1814,75.77921,75.37702,74.97484,74.57265,74.170456,73.76827,73.36608,72.9639,72.56171,72.159515,71.75733,71.35514,71.053055,70.45067,69.848274,69.24588,68.643486,68.04109,67.4387,66.8363,66.23391,65.631516,65.02912,64.42673,63.824333,63.22194,62.619545,62.01715,61.414757,61.113483,59.875385,58.63729,57.399193,56.161095,54.923,53.214317,53.78017,54.346024,54.911877,55.47773,56.043583,56.609436,57.17529,57.741142,58.1524,58.04835,354.50925,329.17365,303.838,278.5024,253.16681,227.83119,202.49559,177.15997,151.82436,132.48323,121.31623,110.14924,99.137924,93.26305,87.38817,81.51329,78.374756,77.97257,77.57038,77.1682,76.76601,76.363815,75.96163,75.55944,75.15726,74.755066,74.35288,73.95069,73.5485,73.14632,72.59397,71.99158,71.38918,70.78679,70.1844,69.58201,68.979614,68.37722,67.774826,67.17243,66.57004,65.96764,65.36525,64.762856,64.16046,63.558067,62.955673,62.35328,61.750885,61.14849,59.94385,58.705757,57.46766,56.229565,54.99147,53.753372,52.868214,53.43407,53.999924,54.565777,55.13163,55.697483,56.263336,56.82919,57.395042,57.9609,58.346397,366.38315,341.04755,315.7119,290.37628,265.04065,239.70502,214.36938,189.03375,163.69814,131.8232,120.65623,109.48925,97.3884,91.51351,85.638626,79.76374,79.36155,78.959366,78.557175,78.15499,77.7528,77.35062,76.948425,76.54624,76.14405,75.74187,75.339676,74.73728,74.13489,73.53249,72.9301,72.327705,71.72531,71.12292,70.52052,69.91814,69.31574,68.71335,68.110954,67.50856,66.906166,66.30377,65.70138,65.09898,64.49659,63.894196,63.2918,62.689407,62.087017,61.250416,60.012318,58.77422,57.53612,56.298023,55.059925,53.82183,51.956272,52.52213,53.087982,53.653835,54.21969,54.78554,55.351395,55.917248,56.4831,57.048958,57.614807,352.92154,327.58594,302.2503,276.91467,251.57907,226.24347,200.90785,175.57224,150.2366,124.901,108.82935,97.66234,89.76398,83.88908,80.750534,80.34835,79.94616,79.54397,79.141785,78.73959,78.3374,77.93522,77.48298,76.880585,76.27819,75.6758,75.0734,74.47101,73.868614,73.26622,72.66383,72.06144,71.459045,70.85665,70.25426,69.65186,69.04947,68.447075,67.84468,67.24229,66.63989,66.037506,65.435104,64.83272,64.23032,63.62793,63.025536,62.42314,61.31888,60.08078,58.842686,57.604588,56.366493,55.128395,53.8903,52.652206,51.610176,52.176033,52.741886,53.30774,53.873592,54.43945,55.005302,55.571156,56.13701,56.702866,57.26872,361.28693,338.05637,314.12415,288.7885,263.45288,238.11725,212.78162,187.44597,162.11034,136.77472,108.16933,97.002365,88.01444,82.13952,81.73733,81.335144,80.93295,80.53076,80.12858,79.62629,79.023895,78.4215,77.81911,77.21671,76.61432,76.011925,75.40953,74.80714,74.20474,73.60235,72.999954,72.39757,71.79517,71.19278,70.590385,69.98799,69.3856,68.7832,68.18081,67.578415,66.97602,66.373634,65.77124,65.168846,64.56645,63.964058,63.361664,62.62544,61.38734,60.149242,58.911148,57.67305,56.43495,55.196854,53.95876,52.72066,50.698235,51.264088,51.82994,52.395798,52.96165,53.527504,54.093357,54.65921,55.225063,55.790916,56.35677,339.05396,315.82336,292.59277,269.36218,246.13156,222.90097,199.31952,173.98395,148.64836,123.312775,97.97719,86.26483,83.12631,82.72413,82.32194,81.76959,81.1672,80.564804,79.96242,79.36002,78.75763,78.155235,77.55284,76.95045,76.34805,75.74566,75.143265,74.54087,73.93848,73.33609,72.733696,72.1313,71.52891,70.92651,70.32412,69.721725,69.11933,68.51694,67.91454,67.31215,66.70976,66.10737,65.504974,64.90258,64.300186,63.697792,62.693905,61.455807,60.21771,58.97961,57.741512,56.503414,55.265316,54.027218,52.78912,51.55102,50.352146,50.918,51.483856,52.04971,52.615562,53.181416,53.74727,54.31312,54.878975,55.444828,56.01068,340.05225,316.82162,293.591,270.36035,247.12973,223.8991,200.66846,177.43782,154.20718,130.97656,107.74591,84.5153,83.9129,83.31051,82.708115,82.10572,81.50333,80.90093,80.298546,79.69615,79.09376,78.49136,77.88897,77.286575,76.68418,76.08179,75.47939,74.877,74.274605,73.67221,73.069824,72.46743,71.865036,71.26264,70.66025,70.05785,69.45546,68.853065,68.25067,67.64828,67.04588,66.44349,65.841095,65.23871,64.63631,64.000465,62.762367,61.52427,60.28617,59.048077,57.80998,56.57188,55.333786,54.095688,52.85759,51.61949,50.381397,50.00605,50.571903,51.137756,51.70361,52.269463,52.83532,53.401173,53.967026,54.53288,55.098732,317.81943,294.5888,271.35815,248.12752,224.8969,201.66626,178.43564,155.20502,131.97437,109.91834,89.03685,84.24902,83.64664,83.04424,82.44185,81.839455,81.23706,80.63467,80.03227,79.42988,78.827484,78.22509,77.622696,77.02031,76.417915,75.81552,75.21313,74.61073,74.00834,73.405945,72.80355,72.20116,71.59877,70.996376,70.39398,69.79159,69.18919,68.5868,67.984406,67.38201,66.77962,66.17723,65.57484,64.97244,64.068924,62.83083,61.59273,60.354633,59.11654,57.87844,56.640343,55.402245,54.164146,52.92605,51.68795,50.449852,49.211754,49.65996,50.225815,50.791668,51.35752,51.923378,52.48923,53.055084,53.620937,54.18679,54.752644,318.8172,295.58655,272.35596,249.12534,225.89471,202.6641,179.43347,156.20287,135.32129,114.4397,90.05225,86.70023,83.982765,83.38037,82.77798,82.17558,81.57319,80.970795,80.3684,79.76601,79.16361,78.56122,77.958824,77.35643,76.75404,76.15165,75.549255,74.94686,74.34447,73.74207,73.13968,72.537285,71.93489,71.3325,70.7301,70.12771,69.525314,68.92292,68.320526,67.71814,67.11574,66.51335,65.91096,65.37547,64.137375,62.899277,61.66118,60.423084,59.184986,57.94689,56.708794,55.470695,54.232597,52.994503,51.756405,50.51831,49.280212,48.74802,49.313873,49.879726,50.44558,51.011433,51.577286,52.143143,52.708992,53.27485,53.840702,296.58438,273.35376,250.12318,226.89258,203.66197,181.60588,160.72433,139.84277,118.96122,98.07967,89.468735,86.11671,83.71649,83.1141,82.5117,81.90931,81.30692,80.70453,80.102135,79.49974,78.89735,78.29495,77.69256,77.090164,76.48777,75.885376,75.28299,74.68059,74.0782,73.47581,72.87341,72.27102,71.668625,71.06623,70.46384,69.86144,69.25905,68.656654,68.05426,67.45187,66.84948,66.247086,65.44394,64.20584,62.967743,61.72965,60.49155,59.253456,58.015358,56.777264,55.539165,54.30107,53.062973,51.824875,50.58678,49.348686,48.110588,48.401924,48.967777,49.53363,50.099483,50.665337,51.231194,51.797047,52.3629,52.928753,53.494606,297.58218,274.35162,251.12103,227.89044,207.00885,186.12727,165.24568,144.3641,123.482506,95.5892,92.2372,88.8852,85.5332,83.45024,82.84785,82.24545,81.64306,81.040665,80.43827,79.83588,79.23348,78.63109,78.028694,77.4263,76.823906,76.22151,75.61912,75.01672,74.41433,73.811935,73.20954,72.60715,72.00476,71.40236,70.79997,70.19757,69.595184,68.99279,68.390396,67.788,67.18561,66.750496,65.512405,64.27431,63.03621,61.79811,60.560013,59.32192,58.08382,56.845722,55.607628,54.36953,53.13143,51.893333,50.65524,49.417145,48.179047,47.489983,48.055836,48.62169,49.187542,49.753395,50.31925,50.8851,51.45096,52.01681,52.582664,275.3495,253.29344,232.41188,211.5303,190.64874,169.76718,148.88562,128.00404,107.12248,95.0057,91.65369,88.30168,84.94967,83.18397,82.58157,81.97918,81.376785,80.77439,80.172,79.56961,78.96722,78.36482,77.76243,77.160034,76.55764,75.955246,75.35285,74.75046,74.14806,73.54567,72.943275,72.34088,71.73849,71.13609,70.53371,69.93131,69.32892,68.726524,68.12413,67.521736,66.81896,65.58087,64.34277,63.104675,61.866577,60.628483,59.390385,58.15229,56.914192,55.676098,54.438,53.199905,51.961807,50.72371,49.485615,48.24752,47.009422,47.143887,47.70974,48.275593,48.841446,49.4073,49.973152,50.53901,51.104862,51.670715,52.23657,278.69644,257.8149,236.93335,216.0518,195.17026,174.2887,153.40715,132.5256,111.64404,97.7742,94.42218,91.07017,87.71815,83.520096,82.9177,82.31531,81.71291,81.11052,80.508125,79.90573,79.30334,78.70094,78.09855,77.496155,76.89377,76.291374,75.68898,75.086586,74.48419,73.8818,73.2794,72.67701,72.074615,71.47222,70.86983,70.26744,69.66504,69.06265,68.46026,68.12553,66.88743,65.64933,64.41124,63.173138,61.935043,60.696945,59.458847,58.22075,56.982655,55.744556,54.506462,53.268364,52.030266,50.792168,49.55407,48.315975,47.077877,46.231945,46.7978,47.36365,47.929504,48.495358,49.06121,49.627064,50.192917,50.758774,51.324627,262.3363,241.45473,220.57315,199.69157,178.81001,157.92844,137.04688,116.16531,100.54265,97.19064,93.83863,90.48662,87.13461,83.7826,82.651436,82.04904,81.44665,80.84425,80.24186,79.639465,79.03708,78.434685,77.83229,77.2299,76.6275,76.02511,75.422714,74.82032,74.217926,73.61553,73.01314,72.41074,71.80835,71.20596,70.60357,70.001175,69.39878,68.79639,68.19399,66.955894,65.7178,64.4797,63.241604,62.003506,60.765408,59.52731,58.28921,57.051113,55.81302,54.57492,53.336823,52.098724,50.860626,49.622528,48.38443,47.14633,45.908234,45.885857,46.45171,47.017563,47.583416,48.14927,48.715122,49.280975,49.84683,50.41268,50.978535,266.85776,245.97621,225.09465,204.21309,183.33153,162.44997,141.5684,120.68686,103.31114,99.95913,96.60712,93.255104,89.90308,86.55107,82.98756,82.38516,81.782776,81.18038,80.57799,79.97559,79.3732,78.770805,78.16841,77.56602,76.96362,76.36124,75.75884,75.15645,74.554054,73.95166,73.349266,72.74687,72.144485,71.54209,70.9397,70.3373,69.73491,69.132515,68.26246,67.02436,65.78626,64.548164,63.31007,62.07197,60.833874,59.59578,58.35768,57.119583,55.881485,54.64339,53.405293,52.167194,50.9291,49.691,48.452904,47.214806,45.97671,44.973907,45.53976,46.105614,46.671467,47.23732,47.803173,48.369026,48.934883,49.500736,50.06659,250.4974,229.61584,208.7343,187.85275,166.97119,146.08963,125.208084,106.079605,102.72759,99.37558,96.02357,92.671555,89.31954,85.96753,82.72129,82.1189,81.5165,80.91411,80.311714,79.70933,79.10693,78.50454,77.902145,77.29975,76.69736,76.09496,75.49258,74.89018,74.28779,73.685394,73.083,72.480606,71.87822,71.275826,70.67343,70.07104,69.46864,68.330925,67.09283,65.85473,64.61663,63.378532,62.140434,60.902336,59.664238,58.426144,57.188046,55.949947,54.71185,53.47375,52.235657,50.99756,49.75946,48.521362,47.283264,46.045166,44.807068,44.62782,45.193672,45.759525,46.32538,46.89123,47.457085,48.022938,48.58879,49.154644,49.720497,255.01912,234.13754,213.25597,192.37439,171.49283,150.61125,129.72968,108.8481,105.49609,102.14408,98.792076,95.44006,92.08806,88.73605,85.38404,82.45503,81.85264,81.250244,80.64785,80.045456,79.44307,78.840675,78.23828,77.63589,77.03349,76.4311,75.828705,75.22631,74.62392,74.02152,73.41913,72.816734,72.21434,71.611946,71.00955,70.40716,69.63748,68.39938,67.161285,65.92319,64.68509,63.446995,62.208897,60.9708,59.732704,58.494606,57.256508,56.01841,54.780315,53.542217,52.304123,51.066025,49.827927,48.58983,47.35173,46.113636,44.87554,43.715862,44.28172,44.847572,45.413425,45.97928,46.545135,47.11099,47.67684,48.242695,48.80855,238.65878,217.77727,196.89575,176.01422,155.13269,134.25117,113.36966,108.26459,104.912575,101.56056,98.20856,94.856544,91.50453,88.15252,84.80051,82.18877,81.58637,80.98398,80.381584,79.77919,79.176796,78.5744,77.97201,77.36961,76.76722,76.16483,75.56244,74.960045,74.35765,73.75526,73.15286,72.55047,71.948074,71.34568,70.743286,69.70594,68.46785,67.22975,65.99165,64.753555,63.515457,62.27736,61.03926,59.801163,58.563065,57.32497,56.086872,54.848774,53.61068,52.37258,51.134483,49.896385,48.658287,47.42019,46.18209,44.943996,43.705894,43.369778,43.93563,44.501484,45.067337,45.63319,46.199043,46.764896,47.33075,47.896606,48.46246,232.16034,222.29897,201.41736,180.53574,159.65414,138.77252,114.385056,111.03304,107.68104,104.329025,100.97702,97.62501,94.272995,90.92099,87.568985,84.21697,81.9225,81.32011,80.71771,80.11532,79.512924,78.91053,78.30814,77.70575,77.103355,76.50096,75.89857,75.29617,74.69378,74.091385,73.48899,72.8866,72.2842,71.68181,71.012505,69.77441,68.53631,67.29821,66.06011,64.822014,63.58392,62.34582,61.107723,59.869625,58.631527,57.39343,56.155334,54.917236,53.67914,52.44104,51.20294,49.964844,48.726746,47.488647,46.25055,45.01245,43.774353,42.457836,43.02369,43.589542,44.155396,44.72125,45.2871,45.852955,46.418808,46.98466,47.550514,201.47409,196.0206,185.05702,164.1755,143.29398,122.41246,113.801544,110.44953,107.09752,103.74551,100.39349,97.04148,93.68947,90.33746,86.98544,83.63344,81.656235,81.05384,80.45145,79.84905,79.24666,78.644264,78.04187,77.439476,76.83708,76.23469,75.63229,75.0299,74.427505,73.82511,73.22272,72.62032,72.01793,71.080956,69.84286,68.60476,67.36666,66.12856,64.89047,63.652374,62.414276,61.176178,59.938084,58.699986,57.46189,56.223793,54.985695,53.7476,52.509506,51.271408,50.03331,48.79521,47.557117,46.31902,45.080925,43.842827,42.60473,42.111736,42.677593,43.243446,43.8093,44.375153,44.94101,45.506863,46.072716,46.638573,47.204426,176.24142,170.78793,165.33444,159.88094,147.81535,119.922005,116.56999,113.21799,109.865974,106.51396,103.16196,99.809944,96.45793,93.10593,89.753914,86.4019,81.992355,81.38996,80.78757,80.18517,79.58278,78.980385,78.37799,77.775604,77.17321,76.570816,75.96842,75.36603,74.76363,74.16124,73.558846,72.95645,72.38751,71.14942,69.91132,68.673225,67.43513,66.19703,64.95893,63.720837,62.48274,61.244644,60.006546,58.768448,57.53035,56.29225,55.054157,53.81606,52.577965,51.339867,50.10177,48.86367,47.625576,46.387478,45.14938,43.911285,42.673187,41.199795,41.765648,42.331505,42.897358,43.46321,44.029064,44.594917,45.16077,45.726624,46.29248,145.55524,140.10175,134.64825,129.19475,123.74125,119.3385,115.98649,112.634476,109.28246,105.93045,102.57844,99.226425,95.874405,92.5224,89.17038,85.818375,82.466354,81.123695,80.5213,79.918915,79.31652,78.71413,78.11173,77.50934,76.906944,76.30455,75.702156,75.09976,74.49737,73.89497,73.29258,72.45598,71.21788,69.97979,68.74169,67.50359,66.265495,65.027405,63.789303,62.55121,61.31311,60.075012,58.836918,57.59882,56.360725,55.122627,53.88453,52.646435,51.408337,50.170242,48.932144,47.694046,46.455948,45.217854,43.979755,42.74166,41.503563,40.8537,41.41955,41.98541,42.55126,43.117115,43.68297,44.248825,44.81468,45.38053,45.946384,124.908516,122.89453,120.88055,118.86656,117.70878,117.51426,118.75496,115.40295,112.050934,108.69892,105.34691,101.994896,98.64288,95.29087,91.93886,88.586845,85.23483,81.45982,80.85743,80.255035,79.65264,79.05025,78.44785,77.84546,77.24307,76.64068,76.038284,75.43589,74.833496,74.2311,73.76254,72.524445,71.28635,70.04825,68.81016,67.57206,66.33396,65.09586,63.857765,62.619667,61.381573,60.143475,58.905376,57.667282,56.429184,55.191086,53.952988,52.714893,51.476795,50.2387,49.000603,47.762505,46.524406,45.28631,44.04821,42.81012,41.57202,39.941757,40.50761,41.073463,41.63932,42.205173,42.771027,43.33688,43.902733,44.46859,45.034443,117.725586,115.71159,114.50031,114.30579,114.111275,113.91676,113.722244,113.527725,111.46741,108.1154,104.7634,101.411385,98.05938,94.70737,91.35536,88.00336,84.651344,81.29933,80.59117,79.98878,79.38638,78.78399,78.181595,77.5792,76.97681,76.37441,75.77202,75.16963,74.56723,73.83101,72.59291,71.35481,70.116714,68.87862,67.64052,66.40242,65.16432,63.926228,62.68813,61.45003,60.211937,58.97384,57.73574,56.497643,55.259544,54.021446,52.783348,51.54525,50.307156,49.069054,47.83096,46.592865,45.354763,44.11667,42.87857,41.640472,40.402374,39.595665,40.161522,40.727375,41.29323,41.85908,42.424934,42.99079,43.556644,44.122498,44.688354,112.556625,111.29185,111.09733,110.90281,110.70829,110.51377,110.31926,110.12474,109.93022,110.883865,107.53186,104.179855,100.82784,97.47584,94.12383,90.77182,87.419815,84.0678,80.9273,80.324905,79.72251,79.12012,78.51772,77.91533,77.312935,76.71054,76.10815,75.50575,75.13757,73.899475,72.66138,71.42328,70.18518,68.94708,67.708984,66.47089,65.232796,63.994698,62.7566,61.5185,60.280403,59.04231,57.80421,56.566116,55.32802,54.08992,52.85182,51.613724,50.375626,49.137527,47.89943,46.661335,45.42324,44.185143,42.947044,41.708946,40.470848,38.683716,39.24957,39.815422,40.381275,40.94713,41.512985,42.07884,42.64469,43.210545,44.167763,107.888855,107.694336,107.499825,107.305305,107.11079,106.916275,106.721756,106.52724,106.33272,106.13821,105.94369,103.59632,100.24431,96.8923,93.54029,90.188286,86.83627,83.48427,80.661026,80.05863,79.45624,78.85385,78.25146,77.64906,77.04667,76.444275,75.84189,75.20604,73.96794,72.72984,71.491745,70.25365,69.01555,67.77745,66.53935,65.301254,64.063156,62.82506,61.586964,60.348866,59.11077,57.872673,56.634575,55.396477,54.15838,52.92028,51.682182,50.444084,49.205986,47.96789,46.72979,45.491695,44.253597,43.0155,41.777405,40.539307,39.301205,38.337627,38.90348,39.469334,40.035187,40.60104,41.166893,41.732746,42.2986,42.86445,42.182877,104.48587,104.29135,104.09684,103.90232,103.7078,103.51328,103.31877,103.12425,102.92973,102.735214,102.5407,102.34618,103.01278,99.660774,96.30876,92.95676,89.60475,86.25274,82.900734,80.39476,79.79237,79.18998,78.587585,77.98519,77.3828,76.78041,76.17802,75.2745,74.03641,72.79831,71.56021,70.32211,69.084015,67.84592,66.60782,65.36972,64.13163,62.893528,61.655434,60.417336,59.179237,57.94114,56.70304,55.464947,54.22685,52.98875,51.750656,50.512558,49.27446,48.03636,46.798264,45.560165,44.32207,43.083973,41.84588,40.60778,39.369682,37.42568,37.99153,38.557384,39.123238,39.68909,40.254944,40.8208,41.386654,42.294952,41.246475,100.888374,100.693855,100.49934,100.304825,100.110306,99.91579,99.721275,99.52676,99.33224,99.137726,98.94321,98.74869,98.55417,98.35966,95.72527,92.37325,89.02123,85.66922,82.3172,80.128494,79.5261,78.923706,78.32131,77.71892,77.11653,76.51414,75.34295,74.10485,72.86675,71.628654,70.390564,69.152466,67.91437,66.67627,65.43817,64.20007,62.96198,61.72388,60.485786,59.24769,58.00959,56.771492,55.533398,54.2953,53.057205,51.819107,50.58101,49.34291,48.104816,46.86672,45.628624,44.390522,43.152428,41.91433,40.676235,39.438137,38.20004,37.07959,37.645443,38.211296,38.77715,39.343002,39.908855,40.47471,41.040565,40.31007,39.261593,97.48538,97.29087,97.09635,96.90183,96.70732,96.5128,96.31828,96.123764,95.92925,95.73473,95.540215,95.3457,95.151184,94.956665,94.762146,95.14174,91.78972,88.4377,85.08568,80.464615,79.86222,79.25983,78.65743,78.055046,77.45265,76.649506,75.41141,74.17331,72.93521,71.69711,70.459015,69.220924,67.98283,66.74473,65.50663,64.26853,63.030437,61.79234,60.55424,59.316147,58.07805,56.83995,55.601852,54.363758,53.12566,51.88756,50.649467,49.41137,48.17327,46.935173,45.69708,44.45898,43.220882,41.982788,40.74469,39.50659,38.268494,36.16765,36.7335,37.299355,37.865208,38.43106,38.99691,39.562763,40.422142,39.373665,38.325188,93.887886,93.69337,93.498856,93.30434,93.10982,92.915306,92.72079,92.52627,92.33175,92.13724,91.94272,91.7482,91.55369,91.35917,91.16465,90.97014,90.77562,87.85419,84.50218,81.15017,79.59597,78.99357,78.391174,77.78878,76.71797,75.47987,74.241776,73.00368,71.76558,70.52749,69.28939,68.05129,66.813194,65.575096,64.337,63.098904,61.86081,60.62271,59.384613,58.146515,56.90842,55.670326,54.432228,53.19413,51.95603,50.717937,49.47984,48.241745,47.003647,45.76555,44.52745,43.289356,42.051258,40.813164,39.575066,38.33697,37.09887,35.860775,36.387405,36.95326,37.51911,38.084965,38.650818,39.21667,38.437256,37.38878,36.3403,90.4849,90.29038,90.09587,89.90135,89.70683,89.512314,89.3178,89.12328,88.928764,88.73425,88.539734,88.345215,88.150696,87.956184,87.761665,87.56715,87.37263,87.178116,87.27065,83.91864,79.93209,79.3297,78.7273,78.02453,76.78643,75.54834,74.31024,73.07214,71.834045,70.59595,69.35785,68.11975,66.88166,65.64356,64.405464,63.167366,61.929268,60.69117,59.453075,58.214977,56.976883,55.738785,54.500687,53.26259,52.024494,50.786396,49.548298,48.310204,47.072105,45.834007,44.59591,43.35781,42.119717,40.88162,39.643524,38.405426,37.167328,35.92923,35.475464,36.041317,36.60717,37.17302,37.738873,38.54933,37.50085,36.452374,35.403896,86.887405,86.69289,86.49837,86.303856,86.10934,85.91482,85.7203,85.52579,85.33127,85.13675,84.94223,84.74772,84.5532,84.35868,84.16417,83.96965,83.77513,83.58061,83.3861,83.19158,79.9831,79.06343,78.092995,76.8549,75.6168,74.37871,73.14061,71.90251,70.66441,69.426315,68.18822,66.95012,65.71202,64.47392,63.23583,61.99773,60.759636,59.521538,58.28344,57.04534,55.807243,54.569145,53.331047,52.092953,50.854855,49.616756,48.378662,47.140564,45.902466,44.664368,43.42627,42.188175,40.950077,39.71198,38.473885,37.235783,35.997684,34.75959,35.129375,35.695225,36.261078,36.82693,37.392784,36.56445,35.515972,34.467495,33.419014,83.48441,83.2899,83.09538,82.90086,82.706345,82.51183,82.317314,82.122795,81.92828,81.733765,81.539246,81.34473,81.150215,80.955696,80.76118,80.56666,80.37215,80.17763,79.98311,79.78859,79.59408,79.39956,78.16146,76.92336,75.685265,74.447174,73.209076,71.97098,70.73288,69.49478,68.25668,67.018585,65.780495,64.5424,63.3043,62.0662,60.828102,59.590004,58.351906,57.11381,55.875717,54.63762,53.39952,52.161423,50.923325,49.685226,48.447136,47.209034,45.97094,44.73284,43.494743,42.25665,41.018547,39.780453,38.54236,37.304256,36.066162,34.828064,34.217422,34.783276,35.34913,35.91498,36.676517,35.62804,34.579563,33.531086,32.48261,79.88692,79.6924,79.49788,79.30337,79.10885,78.91433,78.71981,78.5253,78.33078,78.13626,77.94174,77.74723,77.55271,77.35819,77.29923,77.5114,77.723564,77.93573,78.147896,78.36006,78.33158,77.83787,77.11707,75.8389,74.56072,73.28255,72.03944,70.80134,69.56324,68.32514,67.08705,65.84895,64.610855,63.372757,62.13466,60.89656,59.658463,58.42037,57.18227,55.94417,54.706078,53.46798,52.22988,50.991783,49.753685,48.51559,47.277493,46.039394,44.8013,43.5632,42.325104,41.087006,39.848907,38.610813,37.37271,36.134617,34.89652,33.658424,33.871334,34.437187,35.003036,35.56889,34.691635,33.643158,32.59468,31.546204,30.497726,76.48393,76.28941,76.094894,75.900375,75.705864,75.511345,75.316826,74.986755,75.19891,75.41108,75.623245,75.8354,76.04757,76.259735,76.47189,76.68406,76.896225,77.10839,77.32055,77.75731,77.263596,76.76989,76.27618,76.11277,74.834595,73.55642,72.278244,71.00007,69.72189,68.44371,67.15552,65.91742,64.67932,63.441227,62.20313,60.96503,59.726936,58.48884,57.25074,56.01264,54.774548,53.53645,52.29835,51.060257,49.82216,48.58406,47.345963,46.10787,44.86977,43.63167,42.393578,41.15548,39.91738,38.679283,37.441185,36.203094,34.964996,33.7269,32.959385,33.525238,34.09109,34.803707,33.75523,32.706753,31.658278,30.6098,29.561323,72.88643,73.098595,73.31075,73.52292,73.735085,73.94725,74.15941,74.371574,74.58374,74.7959,75.008064,75.22023,75.432396,75.644554,75.85672,76.068886,76.281044,76.49321,76.68934,76.195625,75.70191,75.208206,74.71449,74.22078,73.72707,72.55211,71.27393,69.99576,68.71758,67.43941,66.161224,64.88305,63.604874,62.3267,61.048523,59.795395,58.557297,57.319202,56.081104,54.843006,53.604908,52.366814,51.128716,49.890617,48.65252,47.41442,46.176323,44.93823,43.70013,42.462032,41.223938,39.98584,38.74774,37.509644,36.271545,35.03345,33.795353,32.55726,32.613297,33.17915,33.745003,32.81883,31.77035,30.721872,29.673395,28.624916,27.576439,72.05909,72.271255,72.48342,72.69558,72.907745,73.11991,73.33208,73.544235,73.7564,73.96857,74.180725,74.39289,74.60506,74.81722,75.02938,75.24155,75.45371,75.66587,75.62136,75.12765,74.633934,74.14023,73.646515,73.1528,72.659096,72.16538,71.547806,70.26963,68.991455,67.71327,66.4351,65.15692,63.878746,62.600567,61.32239,60.044212,58.766037,57.48786,56.209686,54.91147,53.67337,52.435272,51.197174,49.959076,48.72098,47.482883,46.244785,45.006687,43.76859,42.530495,41.292397,40.0543,38.8162,37.578102,36.340004,35.101906,33.863808,32.62571,31.701357,32.26721,32.9309,31.882423,30.833946,29.78547,28.736992,27.688515,26.640038,71.44391,71.656075,71.86824,72.0804,72.292564,72.50473,72.716896,72.929054,73.14122,73.353386,73.565544,73.77771,73.989876,74.20204,74.4142,74.626366,74.83853,74.553375,74.05966,73.565956,73.07224,72.57853,72.08482,71.59111,71.097404,70.60369,70.10998,69.26532,67.987144,66.70897,65.43079,64.15262,62.87444,61.59626,60.318085,59.03991,57.76173,56.483555,55.205376,53.9272,52.649025,51.370846,50.09267,48.81449,47.551346,46.313248,45.075153,43.837055,42.59896,41.360863,40.122765,38.884666,37.646572,36.408478,35.17038,33.93228,32.694183,31.456089,31.355259,31.921112,30.946014,29.897537,28.84906,27.800583,26.752106,25.703629,24.655151]
+ examples/rasterize/rasterize-test3.txt view
@@ -0,0 +1,4 @@+[((-501,-48),-80.0),((-421,-167),-80.0),((-431,-189),-80.0),((-430,-199),-80.0),((-418,-227),-38.57129),((-397,-258),39.884766),((-410,-267),-80.0),((-432,-259),-1.5870361),((-447,-262),-41.32361),((-451,-276),-42.149414),((-375,-221),54.81807),((-410,-194),75.88132),((-383,-188),48.284355),((-404,-225),37.207848),((-401,-170),-33.527046),((-374,-256),158.54184),((-371,-267),346.42474),((-367,-241),134.81987)]+[(14,11,12),(11,13,12),(13,10,12),(13,17,10),(7,4,8),(6,4,7),(6,5,4),(16,15,5),(17,5,15),(13,5,17),(4,5,13),(13,11,4),(11,3,4),(8,4,3),(3,2,8),(3,11,2),(11,1,2),(14,1,11),(8,2,0),(9,8,0)]+((-449,-257),(-383,-191))+[-42.59036,-42.65867,-42.726974,-42.96707,-43.334618,-43.702164,-44.06971,-44.437256,-44.804802,-45.172348,-45.539894,-45.907444,-46.27499,-46.642536,-47.010082,-47.37763,-47.745174,-48.11272,-48.480267,-48.847813,-49.215363,-49.58291,-49.950455,-50.318,-50.685547,-51.053093,-51.42064,-51.788185,-52.15573,-52.523277,-52.890823,-53.25837,-53.62592,-53.993465,-54.36101,-54.728558,-55.096104,-55.46365,-55.831196,-56.198742,-56.566288,-56.933834,-57.301384,-57.66893,-58.036476,-58.404022,-58.77157,-59.139114,-59.50666,-59.874207,-60.241753,-60.6093,-60.976845,-61.34439,-61.711937,-62.079483,-62.44703,-62.81458,-63.18213,-63.549675,-63.91722,-64.28477,-64.65231,-65.01986,-65.387405,-65.75495,-66.1225,-42.421005,-42.78855,-43.156097,-43.523643,-43.89119,-44.258736,-44.62628,-44.993828,-45.361374,-45.72892,-46.096466,-46.464016,-46.831562,-47.19911,-47.566654,-47.9342,-48.301746,-48.669292,-49.03684,-49.404385,-49.77193,-50.13948,-50.507027,-50.874573,-51.24212,-51.609665,-51.97721,-52.344757,-52.712303,-53.07985,-53.447395,-53.81494,-54.182487,-54.550034,-54.917583,-55.285126,-55.652676,-56.02022,-56.387768,-56.755314,-57.12286,-57.490406,-57.857956,-58.225502,-58.59305,-58.960594,-59.32814,-59.695686,-60.063232,-60.43078,-60.798325,-61.16587,-61.533417,-61.900963,-62.26851,-62.636055,-63.0036,-63.37115,-63.738693,-64.10624,-64.473785,-64.84134,-65.208885,-65.57643,-65.94397,-66.31152,-66.67907,-43.345116,-43.71266,-44.080208,-44.447754,-44.8153,-45.182846,-45.550392,-45.91794,-46.285484,-46.65303,-47.02058,-47.388126,-47.755672,-48.12322,-48.490765,-48.85831,-49.225857,-49.593403,-49.960953,-50.3285,-50.696045,-51.06359,-51.431137,-51.798683,-52.16623,-52.533775,-52.90132,-53.268867,-53.636414,-54.00396,-54.37151,-54.73905,-55.1066,-55.474148,-55.841694,-56.20924,-56.576786,-56.944332,-57.311882,-57.67943,-58.046974,-58.41452,-58.782066,-59.149612,-59.51716,-59.884705,-60.25225,-60.619797,-60.987343,-61.35489,-61.72244,-62.08998,-62.45753,-62.825077,-63.192623,-63.56017,-63.92772,-64.29526,-64.66281,-65.03036,-65.3979,-65.76545,-66.132996,-66.50054,-66.86809,-67.235634,-67.60318,-43.901684,-44.26923,-44.636776,-45.004322,-45.371872,-45.739418,-46.106964,-46.47451,-46.842056,-47.209602,-47.57715,-47.944695,-48.31224,-48.679787,-49.047337,-49.414883,-49.78243,-50.149975,-50.51752,-50.885067,-51.252613,-51.62016,-51.987705,-52.355255,-52.7228,-53.090347,-53.457893,-53.82544,-54.192986,-54.56053,-54.928078,-55.295624,-55.66317,-56.030716,-56.398262,-56.765812,-57.133354,-57.500904,-57.86845,-58.235996,-58.603542,-58.97109,-59.33864,-59.70618,-60.07373,-60.441277,-60.808823,-61.17637,-61.543915,-61.91146,-62.279007,-62.646553,-63.0141,-63.381645,-63.74919,-64.11674,-64.48428,-64.85184,-65.219376,-65.58693,-65.95447,-66.32202,-66.68957,-67.05711,-67.42465,-67.792206,-68.15975,-44.060696,-45.00908,-45.88842,-46.054413,-46.295986,-46.663532,-47.031082,-47.39863,-47.766174,-48.13372,-48.501266,-48.868813,-49.23636,-49.603905,-49.97145,-50.338997,-50.706547,-51.074093,-51.44164,-51.809185,-52.17673,-52.544277,-52.911823,-53.279373,-53.646915,-54.014465,-54.38201,-54.749557,-55.117104,-55.48465,-55.852196,-56.21974,-56.587288,-56.954834,-57.32238,-57.68993,-58.057476,-58.425022,-58.79257,-59.160114,-59.52766,-59.895206,-60.262753,-60.630302,-60.99785,-61.365395,-61.73294,-62.100487,-62.468033,-62.83558,-63.203125,-63.57067,-63.938217,-64.30577,-64.67331,-65.04086,-65.4084,-65.775955,-66.14349,-66.51105,-66.87859,-67.24614,-67.613686,-67.98123,-68.34878,-68.716324,-69.08387,-42.346992,-43.295372,-44.243755,-45.192135,-46.14052,-47.088898,-48.129326,-48.29532,-48.46131,-48.69029,-49.05784,-49.425385,-49.79293,-50.160477,-50.528023,-50.89557,-51.263115,-51.63066,-51.998207,-52.365753,-52.7333,-53.10085,-53.468395,-53.83594,-54.203487,-54.571033,-54.93858,-55.306126,-55.67367,-56.04122,-56.408768,-56.776314,-57.14386,-57.511406,-57.878952,-58.2465,-58.614044,-58.98159,-59.349136,-59.716686,-60.084232,-60.45178,-60.819324,-61.18687,-61.554417,-61.921963,-62.28951,-62.657055,-63.024605,-63.39215,-63.759697,-64.12724,-64.49479,-64.862335,-65.22988,-65.59743,-65.96497,-66.33252,-66.700066,-67.06761,-67.435165,-67.802704,-68.17026,-68.537796,-68.90535,-69.27289,-69.64044,-41.58169,-42.53007,-43.47845,-44.426826,-45.375206,-46.323586,-47.271965,-48.220345,-49.168724,-50.117104,-50.536224,-50.702217,-50.86821,-51.084595,-51.45214,-51.819687,-52.187233,-52.55478,-52.922325,-53.28987,-53.657417,-54.024963,-54.392513,-54.76006,-55.127605,-55.49515,-55.862698,-56.230244,-56.59779,-56.96534,-57.332886,-57.70043,-58.067978,-58.435524,-58.80307,-59.170616,-59.538162,-59.90571,-60.273254,-60.640804,-61.00835,-61.375896,-61.743443,-62.11099,-62.478535,-62.846085,-63.21363,-63.581177,-63.948723,-64.31627,-64.683815,-65.05136,-65.41891,-65.78645,-66.154,-66.521545,-66.88909,-67.25664,-67.62419,-67.99173,-68.35928,-68.72683,-69.094376,-69.46192,-69.82947,-70.197014,-70.56456,-38.22489,-40.81637,-41.764748,-42.713127,-43.661507,-44.609886,-45.558266,-46.506645,-47.455025,-48.403404,-49.351788,-50.300167,-51.248547,-52.196926,-52.77713,-52.943123,-53.109116,-53.275112,-53.478897,-53.846443,-54.21399,-54.581535,-54.94908,-55.316628,-55.684174,-56.05172,-56.41927,-56.786816,-57.15436,-57.521908,-57.889454,-58.257,-58.624546,-58.992092,-59.359642,-59.72719,-60.094734,-60.46228,-60.829826,-61.197372,-61.56492,-61.932465,-62.30001,-62.667557,-63.035103,-63.402653,-63.7702,-64.13774,-64.505295,-64.87284,-65.24039,-65.60793,-65.97548,-66.343025,-66.71057,-67.07812,-67.44566,-67.81321,-68.180756,-68.5483,-68.91585,-69.283394,-69.65094,-70.01849,-70.38603,-70.753586,-71.121124,-36.336792,-38.8735,-40.99943,-41.947815,-42.896194,-43.844574,-44.792957,-45.741337,-46.689716,-47.6381,-48.58648,-49.53486,-50.48324,-51.43162,-52.38,-53.32838,-54.276764,-55.01804,-55.184032,-55.350025,-55.516018,-55.68201,-55.8732,-56.240746,-56.60829,-56.975838,-57.343384,-57.71093,-58.078476,-58.446026,-58.813572,-59.181118,-59.548664,-59.91621,-60.283756,-60.651302,-61.01885,-61.3864,-61.753944,-62.12149,-62.489037,-62.856583,-63.22413,-63.591675,-63.95922,-64.32677,-64.69431,-65.06186,-65.429405,-65.79695,-66.164505,-66.53204,-66.8996,-67.26714,-67.63469,-68.002235,-68.36978,-68.73733,-69.10487,-69.47242,-69.839966,-70.20751,-70.57506,-70.942604,-71.31015,-71.6777,-72.04524,-31.912018,-34.44872,-36.98542,-40.234123,-41.182503,-42.130882,-43.079266,-44.027645,-44.976025,-45.924404,-46.872787,-47.821167,-48.769547,-49.717926,-50.666306,-51.61469,-52.56307,-53.511448,-54.45983,-55.40821,-56.35659,-57.25895,-57.424942,-57.590935,-57.756927,-57.92292,-58.088913,-58.2675,-58.635048,-59.002594,-59.37014,-59.737686,-60.105232,-60.47278,-60.84033,-61.207874,-61.57542,-61.942966,-62.310513,-62.67806,-63.045605,-63.41315,-63.7807,-64.14825,-64.51579,-64.88334,-65.250885,-65.61843,-65.98598,-66.35352,-66.72107,-67.088615,-67.45616,-67.82371,-68.19125,-68.5588,-68.926346,-69.2939,-69.661446,-70.02899,-70.39654,-70.764084,-71.13163,-71.499176,-71.86672,-72.23427,-72.601814,-30.02391,-32.560616,-35.09732,-37.634026,-40.170734,-41.36557,-42.31395,-43.26233,-44.21071,-45.15909,-46.107468,-47.05585,-48.00423,-48.95261,-49.90099,-50.84937,-51.79775,-52.746128,-53.694508,-54.64289,-55.59127,-56.53965,-57.48803,-58.43641,-59.38479,-59.665844,-59.831837,-59.99783,-60.163822,-60.32982,-60.49581,-60.661804,-61.02935,-61.396896,-61.764442,-62.13199,-62.499535,-62.867085,-63.23463,-63.602177,-63.969723,-64.337265,-64.70482,-65.072365,-65.43991,-65.80746,-66.175,-66.54255,-66.910095,-67.27764,-67.64519,-68.01273,-68.38028,-68.747826,-69.11537,-69.48292,-69.850464,-70.21801,-70.585556,-70.9531,-71.32065,-71.6882,-72.05575,-72.423294,-72.79084,-73.15839,-73.52593,-25.599129,-28.135826,-30.672523,-33.20922,-35.74592,-38.282616,-40.600246,-41.548626,-42.49701,-43.44539,-44.39377,-45.34215,-46.29053,-47.238914,-48.187294,-49.135674,-50.084057,-51.032436,-51.98082,-52.9292,-53.87758,-54.825962,-55.774345,-56.722725,-57.671104,-58.619484,-59.567867,-60.516247,-61.74076,-61.906754,-62.072746,-62.23874,-62.40473,-62.570724,-62.736717,-62.90271,-63.056107,-63.423653,-63.7912,-64.158745,-64.52629,-64.89384,-65.26138,-65.62893,-65.996475,-66.36402,-66.731575,-67.09912,-67.46667,-67.83421,-68.20176,-68.569305,-68.93685,-69.3044,-69.67194,-70.03949,-70.407036,-70.77458,-71.14213,-71.509674,-71.87722,-72.24477,-72.61231,-72.97986,-73.347404,-73.71495,-74.0825,-23.711018,-26.247719,-28.78442,-31.321123,-33.857826,-36.394524,-38.93123,-40.783314,-41.731697,-42.680077,-43.628456,-44.576836,-45.52522,-46.4736,-47.421978,-48.37036,-49.31874,-50.26712,-51.2155,-52.16388,-53.112263,-54.060642,-55.00902,-55.957405,-56.905785,-57.854164,-58.802544,-59.750923,-60.699306,-61.64769,-62.59607,-63.54445,-64.14766,-64.31365,-64.479645,-64.64564,-64.81163,-64.97762,-65.143616,-65.30961,-65.4756,-65.817955,-66.1855,-66.55305,-66.92059,-67.28814,-67.655685,-68.02324,-68.390785,-68.75833,-69.12588,-69.49342,-69.86097,-70.228516,-70.59606,-70.96361,-71.331154,-71.6987,-72.066246,-72.43379,-72.80134,-73.168884,-73.53643,-73.90398,-74.27153,-74.63908,-75.00662,-19.286198,-21.822903,-24.35961,-26.896313,-29.43302,-31.969725,-34.50643,-37.043137,-40.018,-40.96638,-41.91476,-42.863144,-43.811523,-44.759903,-45.708282,-46.656666,-47.605045,-48.553425,-49.50181,-50.450188,-51.398567,-52.346947,-53.295326,-54.24371,-55.19209,-56.14047,-57.088852,-58.03723,-58.98561,-59.93399,-60.882374,-61.830753,-62.779137,-63.727516,-64.675896,-65.624275,-66.388565,-66.55456,-66.72055,-66.88654,-67.052536,-67.21853,-67.38452,-67.550514,-67.716515,-67.84471,-68.21226,-68.5798,-68.94735,-69.314896,-69.68244,-70.04999,-70.41754,-70.78509,-71.15263,-71.52018,-71.887726,-72.25527,-72.62282,-72.990364,-73.35791,-73.72546,-74.093,-74.46055,-74.828094,-75.19564,-75.56319,-17.398142,-19.934845,-22.471546,-25.008247,-27.544949,-30.081652,-32.618355,-35.155056,-37.691757,-40.201073,-41.149452,-42.09783,-43.04621,-43.994595,-44.942974,-45.891354,-46.839737,-47.788116,-48.736496,-49.684875,-50.633255,-51.58164,-52.530018,-53.4784,-54.42678,-55.37516,-56.32354,-57.27192,-58.220303,-59.168686,-60.117065,-61.065445,-62.013824,-62.962204,-63.910587,-64.85896,-65.80734,-66.75573,-67.70411,-68.62947,-68.79546,-68.96146,-69.12745,-69.29344,-69.459435,-69.62543,-69.79143,-69.95742,-70.12341,-70.289406,-70.60656,-70.974106,-71.34165,-71.7092,-72.076744,-72.4443,-72.811844,-73.17939,-73.546936,-73.91448,-74.28203,-74.649574,-75.01712,-75.38467,-75.75221,-76.11976,-76.487305,-12.973322,-15.510026,-18.04673,-20.583435,-23.12014,-25.656845,-28.193548,-30.730253,-33.266956,-35.803665,-38.34037,-40.384136,-41.33252,-42.2809,-43.22928,-44.177658,-45.12604,-46.07442,-47.0228,-47.971184,-48.919563,-49.867943,-50.816322,-51.7647,-52.713085,-53.661465,-54.609844,-55.558228,-56.506607,-57.454987,-58.403366,-59.35175,-60.30013,-61.24851,-62.19689,-63.14527,-64.09365,-65.04203,-65.99041,-66.9388,-67.88718,-68.835556,-69.783936,-70.870384,-71.03638,-71.20237,-71.36836,-71.534355,-71.70035,-71.86634,-72.03233,-72.198326,-72.36432,-72.53031,-72.633316,-73.00086,-73.36841,-73.735954,-74.1035,-74.471054,-74.8386,-75.20615,-75.57369,-75.94124,-76.308784,-76.67633,-77.04388,-11.085267,-13.621969,-16.15867,-18.695372,-21.232073,-23.768774,-26.305477,-28.84218,-31.378881,-33.91558,-36.452286,-38.988987,-40.567207,-41.515587,-42.46397,-43.41235,-44.36073,-45.30911,-46.257492,-47.20587,-48.15425,-49.10263,-50.05101,-50.999393,-51.947773,-52.896152,-53.844532,-54.792915,-55.741295,-56.689674,-57.638054,-58.586433,-59.534813,-60.483196,-61.43158,-62.379955,-63.32834,-64.27672,-65.2251,-66.17348,-67.12186,-68.07024,-69.018616,-69.966995,-70.91538,-71.86376,-72.81214,-73.27728,-73.443275,-73.60927,-73.77526,-73.94125,-74.10725,-74.27324,-74.43923,-74.605225,-74.77122,-74.93721,-75.1032,-75.395164,-75.76271,-76.130264,-76.49781,-76.86536,-77.2329,-77.60045,-77.967995,-6.6604395,-9.197142,-11.733843,-14.270544,-16.807247,-19.343948,-21.88065,-24.41735,-26.954052,-29.490753,-32.02746,-34.564156,-37.10086,-39.80188,-40.75026,-41.698643,-42.647022,-43.5954,-44.543785,-45.492165,-46.440544,-47.388927,-48.337307,-49.28569,-50.23407,-51.18245,-52.130833,-53.079212,-54.02759,-54.975975,-55.924355,-56.872734,-57.821117,-58.7695,-59.71788,-60.66626,-61.61464,-62.563023,-63.511406,-64.459785,-65.408165,-66.356544,-67.30493,-68.25331,-69.20169,-70.15007,-71.09845,-72.04683,-72.99521,-73.94359,-74.891975,-75.51819,-75.68418,-75.850174,-76.01617,-76.18216,-76.34815,-76.514145,-76.68014,-76.84613,-77.01212,-77.178116,-77.34411,-77.42192,-77.78947,-78.15702,-78.52457,-4.7723694,-7.3090696,-9.845771,-12.382471,-14.919172,-17.455872,-19.992573,-22.529274,-25.065975,-27.602676,-30.139378,-32.67608,-35.212776,-37.749477,-39.98495,-40.93333,-41.88171,-42.830093,-43.778473,-44.726852,-45.675232,-46.623615,-47.571995,-48.520374,-49.468758,-50.417137,-51.365517,-52.313896,-53.26228,-54.21066,-55.15904,-56.10742,-57.0558,-58.00418,-58.95256,-59.900944,-60.849323,-61.797703,-62.746086,-63.694466,-64.642845,-65.591225,-66.539604,-67.48799,-68.43637,-69.38475,-70.33313,-71.28151,-72.22989,-73.17827,-74.12665,-75.07503,-76.023415,-76.971794,-77.75909,-77.92509,-78.09108,-78.25707,-78.423065,-78.58906,-78.75505,-78.92104,-79.087036,-79.25303,-79.41902,-79.585014,-79.75101,-7.765863,-7.4176664,-7.06947,-7.9576645,-10.494367,-13.031069,-15.56777,-18.104471,-20.641174,-23.177876,-25.714577,-28.25128,-30.78798,-33.324684,-35.861385,-38.398087,-40.168015,-41.116398,-42.064777,-43.013157,-43.96154,-44.90992,-45.8583,-46.80668,-47.755062,-48.70344,-49.65182,-50.600204,-51.548584,-52.496964,-53.445343,-54.393723,-55.342106,-56.290485,-57.23887,-58.18725,-59.135628,-60.084007,-61.032387,-61.980766,-62.92915,-63.877533,-64.82591,-65.77429,-66.72267,-67.67105,-68.61943,-69.56781,-70.51619,-71.46457,-72.41296,-73.361336,-74.309715,-75.258095,-76.20648,-77.15486,-78.10324,-79.05162,-80.0,-79.2396,-78.4792,-77.71881,-76.95841,-76.19801,-75.43762,-74.67722,-73.916824,-11.029373,-10.681177,-10.332982,-9.984787,-9.636591,-11.142961,-13.679665,-16.21637,-18.753075,-21.289776,-23.82648,-26.363186,-28.899889,-31.436594,-33.973297,-36.510002,-39.046707,-40.351086,-41.299465,-42.24785,-43.196228,-44.144608,-45.092987,-46.041367,-46.98975,-47.93813,-48.88651,-49.834892,-50.78327,-51.73165,-52.68003,-53.62841,-54.57679,-55.525173,-56.473553,-57.421932,-58.370316,-59.318695,-60.267075,-61.215454,-62.163834,-63.112213,-64.06059,-65.00897,-65.95735,-66.90574,-67.85411,-68.8025,-69.75088,-70.69926,-71.64764,-72.59602,-73.544395,-74.49278,-75.44116,-76.38954,-75.14707,-73.46642,-72.01583,-71.25544,-70.49504,-69.73464,-68.97424,-68.21385,-67.45345,-66.693054,-65.932655,-14.641076,-14.292881,-13.944685,-13.596489,-13.248294,-12.900098,-12.551903,-11.791591,-14.328294,-16.864996,-19.4017,-21.9384,-24.475105,-27.011806,-29.548512,-32.085213,-34.621914,-37.158615,-39.585773,-40.534153,-41.482533,-42.430916,-43.379295,-44.327675,-45.276054,-46.224438,-47.172817,-48.121197,-49.06958,-50.01796,-50.96634,-51.91472,-52.863102,-53.81148,-54.759865,-55.708244,-56.656624,-57.605003,-58.553383,-59.501762,-60.450146,-61.398525,-62.34691,-63.295288,-64.24367,-65.19205,-66.14043,-67.088806,-68.037186,-68.98557,-69.93395,-70.88233,-71.83071,-73.65542,-71.97478,-70.29413,-68.61348,-66.93284,-65.25219,-64.03167,-63.27127,-62.510876,-61.75048,-60.99008,-60.229687,-59.46929,-58.708897,-17.904593,-17.556396,-17.2082,-16.860004,-16.511808,-16.163612,-15.815416,-15.46722,-15.119024,-14.976886,-17.513586,-20.050287,-22.586988,-25.12369,-27.66039,-30.197092,-32.733795,-35.270493,-37.807198,-39.76883,-40.71721,-41.66559,-42.61397,-43.56235,-44.51073,-45.459114,-46.407494,-47.355873,-48.304253,-49.252636,-50.20102,-51.1494,-52.09778,-53.046158,-53.994537,-54.94292,-55.891304,-56.839684,-57.788063,-58.736443,-59.684822,-60.633205,-61.58159,-62.52997,-63.478348,-64.42673,-65.37511,-66.32349,-67.271866,-68.22025,-69.16863,-68.8025,-67.12185,-65.4412,-63.760555,-62.079906,-60.39926,-58.718613,-57.037964,-56.047504,-55.28711,-54.52671,-53.766315,-53.00592,-52.24552,-51.485126,-50.72473,-21.516296,-21.1681,-20.819904,-20.471708,-20.123512,-19.775316,-19.42712,-19.078924,-18.730728,-18.382532,-18.034336,-17.68614,-18.16222,-20.698917,-23.235619,-25.772316,-28.309015,-30.845715,-33.382416,-35.919113,-39.003517,-39.951897,-40.90028,-41.84866,-42.79704,-43.745422,-44.6938,-45.64218,-46.59056,-47.53894,-48.487324,-49.435703,-50.384083,-51.332466,-52.280846,-53.229225,-54.177605,-55.125984,-56.074368,-57.022747,-57.971127,-58.91951,-59.86789,-60.81627,-61.76465,-62.713028,-63.66141,-64.60979,-65.55817,-65.63022,-63.949574,-62.268925,-60.588276,-58.907627,-57.226982,-55.546333,-53.865685,-52.185036,-50.504387,-48.82374,-48.06334,-47.302944,-46.542545,-45.78215,-45.02175,-44.261356,-43.500957,-24.779812,-24.431616,-24.08342,-23.735224,-23.387028,-23.03883,-22.690634,-22.342438,-21.994242,-21.646046,-21.29785,-20.949654,-20.601458,-20.253262,-21.347513,-23.884214,-26.420918,-28.957619,-31.49432,-34.03102,-36.567722,-39.104424,-40.134964,-41.083347,-42.031727,-42.980106,-43.92849,-44.87687,-45.82525,-46.773632,-47.72201,-48.670395,-49.618774,-50.567154,-51.515533,-52.463917,-53.412296,-54.36068,-55.30906,-56.25744,-57.20582,-58.1542,-59.102585,-60.050964,-60.999344,-61.947723,-62.45792,-60.777275,-59.096626,-57.415977,-55.735332,-54.054688,-52.37404,-50.69339,-49.012745,-47.332096,-45.65145,-43.970802,-42.290157,-40.839573,-40.079174,-39.31878,-38.55838,-37.797985,-37.03759,-36.27719,-35.516796,-28.391518,-28.043322,-27.695126,-27.34693,-26.998734,-26.650537,-26.302341,-25.954145,-25.60595,-25.257753,-24.909557,-24.561361,-24.213165,-23.864971,-23.516773,-23.16858,-21.996107,-24.532812,-27.069517,-29.606222,-32.14293,-34.679634,-37.216335,-39.369656,-40.318035,-41.266415,-42.214794,-43.163177,-44.111557,-45.059937,-46.00832,-46.9567,-47.90508,-48.85346,-49.80184,-50.75022,-51.6986,-52.64698,-53.59536,-54.543743,-55.492123,-56.440506,-57.388885,-58.337265,-59.285645,-57.604996,-55.924347,-54.243702,-52.563053,-50.882404,-49.20176,-47.52111,-45.84046,-44.159813,-42.479164,-40.79852,-39.11787,-37.43722,-35.756577,-33.615803,-32.855404,-32.09501,-31.334612,-30.574215,-29.813818,-29.053421,-27.024725,-31.655024,-31.306828,-30.958632,-30.610435,-30.26224,-29.914043,-29.565847,-29.217651,-28.869457,-28.52126,-28.173065,-27.82487,-27.476673,-27.128477,-26.780281,-26.432085,-26.083889,-25.735693,-25.387497,-27.718142,-30.254845,-32.791546,-35.32825,-37.864952,-39.55272,-40.501102,-41.449482,-42.39786,-43.34624,-44.29462,-45.243004,-46.191383,-47.139763,-48.088142,-49.036522,-49.9849,-50.93328,-51.881664,-52.830044,-53.778423,-54.726803,-55.675182,-54.43272,-52.75207,-51.071423,-49.390778,-47.71013,-46.02948,-44.34883,-42.668182,-40.987534,-39.306885,-37.626236,-35.94559,-34.264942,-32.584297,-30.903646,-29.222998,-27.54235,-25.861704,-24.871243,-24.110847,-23.350452,-22.590055,-21.82966,-21.069263,-21.84894,-35.26674,-34.91854,-34.570347,-34.22215,-33.873955,-33.525757,-33.17756,-32.829365,-32.48117,-32.132973,-31.784777,-31.43658,-31.088385,-30.740189,-30.391993,-30.043797,-29.6956,-29.347404,-28.999207,-28.651012,-28.302814,-28.366735,-30.903444,-33.44015,-35.97686,-38.78741,-39.73579,-40.684174,-41.632553,-42.580933,-43.529312,-44.47769,-45.426075,-46.374454,-47.322834,-48.271217,-49.219597,-50.167976,-51.116356,-52.941067,-51.260418,-49.579773,-47.899124,-46.218475,-44.53783,-42.85718,-41.176537,-39.495888,-37.81524,-36.13459,-34.45395,-32.7733,-31.092651,-29.412004,-27.731356,-26.05071,-24.370062,-22.689415,-21.008766,-19.328117,-17.647472,-16.887075,-16.126678,-15.366282,-14.605886,-13.8454895,-13.628641,-38.530243,-38.18205,-37.83385,-37.485657,-37.13746,-36.789265,-36.441067,-36.092873,-35.744675,-35.39648,-35.048283,-34.70009,-34.35189,-34.003696,-33.6555,-33.307304,-32.959106,-32.61091,-32.262714,-31.914518,-31.566322,-31.218126,-30.86993,-31.552069,-34.08877,-36.625477,-38.970478,-39.918858,-40.867237,-41.815617,-42.763996,-43.712376,-44.66076,-45.60914,-46.557518,-47.505898,-48.454277,-48.088142,-46.407494,-44.72685,-43.0462,-41.36555,-39.684906,-38.004257,-36.32361,-34.64296,-32.962315,-31.281666,-29.601019,-27.92037,-26.239723,-24.559076,-22.87843,-21.19778,-19.517132,-17.836487,-16.155838,-14.475189,-12.79454,-11.113895,-9.663309,-8.902912,-8.142514,-7.3821173,-6.62172,-5.8613224,-8.452904,-42.14195,-41.79375,-41.445557,-41.09736,-40.749165,-40.40097,-40.052773,-39.70458,-39.35638,-39.008186,-38.65999,-38.311794,-37.9636,-37.615402,-37.26721,-36.91901,-36.570816,-36.22262,-35.874424,-35.52623,-35.178032,-34.829838,-34.481644,-34.133446,-33.785248,-32.200665,-34.737362,-37.274063,-39.153534,-40.101913,-41.050293,-41.998672,-42.947056,-43.895435,-44.843815,-44.915867,-43.235218,-41.55457,-39.873924,-38.193275,-36.512627,-34.831978,-33.15133,-31.470684,-29.790035,-28.109386,-26.428738,-24.748089,-23.067444,-21.386795,-19.706146,-18.025497,-16.34485,-14.664202,-12.983555,-11.302906,-9.622257,-7.9416084,-6.2609596,-4.580311,-2.8996658,-1.6791434,-0.9187472,-0.15835106,0.60204506,2.8119414,-0.232615,-45.405464,-45.05727,-44.709072,-44.360878,-44.01268,-43.664482,-43.316288,-42.968094,-42.619896,-42.271698,-41.923504,-41.575306,-41.22711,-40.878914,-40.53072,-40.18252,-39.834328,-39.48613,-39.13793,-38.789738,-38.441544,-38.093346,-37.745148,-37.396954,-37.04876,-36.70056,-36.352364,-36.00417,-37.92268,-39.3366,-40.284985,-41.233368,-41.743565,-40.06292,-38.38227,-36.701622,-35.020973,-33.34033,-31.65968,-29.979033,-28.298386,-26.617737,-24.93709,-23.256441,-21.575796,-19.895147,-18.2145,-16.533852,-14.853207,-13.172558,-11.491911,-9.811264,-8.130615,-6.4499664,-4.7693214,-3.0886726,-1.4080276,0.27262115,1.95327,3.6339188,5.3145638,6.305023,7.0654197,7.825816,8.586212,7.9876804,4.943125,-49.017166,-48.668972,-48.320774,-47.97258,-47.624382,-47.276188,-46.927994,-46.579796,-46.231598,-45.883404,-45.53521,-45.18701,-44.838818,-44.49062,-44.142426,-43.794228,-43.446033,-43.097836,-42.74964,-42.401443,-42.05325,-41.70505,-41.356857,-41.00866,-40.660465,-40.312267,-39.964073,-39.615875,-39.26768,-38.919487,-38.57129,-36.89064,-35.20999,-33.529346,-31.848698,-30.168049,-28.487402,-26.806755,-25.126106,-23.445457,-21.76481,-20.084164,-18.403515,-16.722866,-15.042221,-13.361572,-11.680923,-10.000277,-8.319628,-6.638981,-4.958332,-3.277687,-1.5970383,8.3610535e-2,1.7642593,3.4449081,5.125557,6.806202,8.486847,10.167496,11.848145,13.528793,14.289192,15.04959,15.809989,16.207983,13.163428,-52.280674,-51.93248,-51.584282,-51.236088,-50.887894,-50.539696,-50.1915,-49.843304,-49.49511,-49.14691,-48.798717,-48.45052,-48.102325,-47.754128,-47.405933,-47.05774,-46.70954,-46.361347,-46.01315,-45.664955,-45.316757,-44.968563,-44.62037,-44.27217,-43.923977,-42.484966,-39.955147,-37.425323,-34.895504,-33.824272,-32.360836,-30.127422,-27.894009,-25.660597,-23.63447,-21.953823,-20.273174,-18.592525,-16.911879,-15.231231,-13.550583,-11.869936,-10.189287,-8.508639,-6.8279915,-5.1473427,-3.4666958,-1.786047,-0.105400085,1.5752468,3.2558956,4.9365444,6.617193,8.29784,9.978485,11.659134,13.339783,15.020428,16.70108,18.381725,20.062378,21.512959,22.273352,23.033747,23.79414,21.38376,18.339203,-55.892387,-55.544193,-55.195995,-54.8478,-54.499603,-54.15141,-53.80321,-53.455017,-53.10682,-52.758625,-52.410427,-52.062233,-51.714035,-51.36584,-51.017643,-50.66945,-50.32125,-49.973053,-49.62486,-49.276665,-48.928467,-46.39865,-43.868835,-41.33902,-38.809204,-36.27939,-33.749577,-31.148603,-30.11294,-29.077274,-28.383831,-26.150414,-23.916996,-21.683578,-19.450161,-17.216743,-14.983327,-12.749909,-10.3783,-8.697652,-7.017004,-5.3363566,-3.6557088,-1.9750614,-0.29441357,1.3862343,3.0668812,4.74753,6.428177,8.108826,9.789473,11.470121,13.150768,14.831415,16.512064,18.192709,19.873358,21.554007,23.234653,24.915302,26.595947,28.736723,29.497118,30.257515,32.648613,29.604057,26.559502,-59.155895,-58.8077,-58.459503,-58.11131,-57.76311,-57.414917,-57.06672,-56.718525,-56.37033,-56.022133,-55.67394,-55.32574,-54.977547,-54.62935,-54.281155,-52.842148,-50.312332,-47.782513,-45.252697,-42.722878,-40.19306,-37.663246,-35.13343,-32.60361,-30.073793,-27.543978,-26.40159,-25.365925,-24.33026,-23.294594,-22.173378,-19.939962,-17.706547,-15.473129,-13.239714,-11.006298,-8.772881,-6.539465,-4.3060493,-2.0726318,0.16078377,2.3941994,4.5585194,6.239167,7.919815,9.600462,11.28111,12.961758,14.6424055,16.323053,18.0037,19.68435,21.364996,23.045645,24.726292,26.406939,28.087587,29.768236,31.448883,33.12953,34.81018,36.490826,37.481285,38.24168,37.824352,34.779793,31.735233,-62.767605,-62.41941,-62.071213,-61.72302,-61.37482,-61.026627,-60.67843,-60.330235,-59.982037,-59.633842,-59.285645,-56.75583,-54.226013,-51.696198,-49.16638,-46.636566,-44.106754,-41.57694,-39.047123,-36.517307,-33.98749,-31.457676,-28.927862,-26.398045,-23.72592,-22.690252,-21.654585,-20.618917,-19.58325,-18.547583,-17.511915,-15.962924,-13.729509,-11.496094,-9.262678,-7.0292635,-4.795848,-2.5624332,-0.32901764,1.904398,4.1378136,6.3712273,8.604645,10.838058,13.071474,15.304888,17.538305,19.495338,21.175985,22.856634,24.537281,26.21793,27.898577,29.579226,31.259872,32.94052,34.62117,36.301815,37.982464,39.663113,41.343758,43.024406,44.705055,45.46545,46.044647,43.000088,39.95553,-66.03111,-65.68292,-65.334724,-64.98653,-64.63833,-63.199326,-60.66951,-58.139694,-55.609875,-53.08006,-50.550243,-48.020424,-45.49061,-42.960793,-40.430977,-37.90116,-35.371346,-32.84153,-30.31171,-27.781895,-25.252079,-22.72226,-20.192448,-18.978903,-17.943235,-16.90757,-15.871902,-14.836235,-13.800568,-12.7649,-11.729233,-9.75247,-7.5190554,-5.2856402,-3.052225,-0.81881046,1.4146051,3.6480207,5.8814354,8.114851,10.348265,12.58168,14.815096,17.04851,19.281925,21.51534,23.748755,25.982168,28.215586,30.449,32.68242,34.43216,36.11281,37.793453,39.474102,41.154747,42.835396,44.516045,46.19669,47.877335,49.557983,51.238632,52.689217,53.449623,51.220394,48.175835,45.13128,-69.64282,-67.11301,-64.58319,-62.05337,-59.523552,-56.993736,-54.46392,-51.934105,-49.404285,-46.87447,-44.34465,-41.814835,-39.28502,-36.7552,-34.225384,-31.695568,-29.165749,-26.635933,-24.106117,-21.576298,-19.046482,-16.30322,-15.267556,-14.231891,-13.196225,-12.160561,-11.124895,-10.08923,-9.053564,-8.0178995,-6.982234,-5.775467,-3.5420508,-1.3086348,0.9247813,3.1581974,5.391614,7.6250296,9.858445,12.091862,14.325277,16.558693,18.792109,21.025528,23.258944,25.49236,27.725773,29.95919,32.192608,34.426025,36.65944,38.892857,41.126274,43.359688,45.593105,47.688328,49.368973,51.04962,52.73027,54.410915,56.091564,57.772213,59.452858,62.485287,59.440723,56.39616,53.3516,-60.907425,-58.37761,-55.847794,-53.317978,-50.788162,-48.258343,-45.72853,-43.19871,-40.6689,-38.13908,-35.609264,-33.07945,-30.549637,-28.019817,-25.490002,-22.960186,-20.43037,-17.900555,-15.370739,-12.8409195,-11.556221,-10.520555,-9.484888,-8.449221,-7.4135547,-6.3778877,-5.3422213,-4.306555,-3.2708874,-2.235221,-1.1995544,0.43498707,2.6684027,4.9018183,7.1352334,9.368649,11.602065,13.835481,16.068895,18.30231,20.535727,22.769142,25.002558,27.235975,29.469389,31.702805,33.93622,36.169636,38.403053,40.636467,42.869884,45.1033,47.33671,49.570126,51.803543,54.03696,56.270374,58.50379,60.737206,62.62514,64.30579,65.98644,67.66708,67.661026,64.61646,61.476612,56.33574,-54.701836,-52.172016,-49.6422,-47.112385,-44.58257,-42.052753,-39.522934,-36.993114,-34.463303,-31.933483,-29.403667,-26.873852,-24.344032,-21.814217,-19.2844,-16.754585,-14.22477,-11.694946,-8.880537,-7.84487,-6.8092036,-5.773537,-4.7378707,-3.7022042,-2.6665378,-1.6308713,-0.59520435,0.44046116,1.4761286,2.511795,3.5474606,4.412026,6.645441,8.878857,11.112271,13.345687,15.5791025,17.812517,20.045933,22.279348,24.512762,26.746178,28.979593,31.213009,33.446423,35.67984,37.913254,40.146667,42.380085,44.6135,46.846916,49.08033,51.313744,53.54716,55.78058,58.01399,60.247406,62.480824,64.71423,66.94765,69.18106,71.414474,73.6479,75.88132,70.74044,65.59957,60.458694,-45.966446,-43.43663,-40.90681,-38.37699,-35.84717,-33.317356,-30.787533,-28.257717,-25.727898,-23.198082,-20.668262,-18.138447,-15.608627,-13.078812,-10.548988,-8.019169,-5.4893494,-4.133522,-3.097857,-2.0621917,-1.0265267,9.138107e-3,1.0448031,2.0804682,3.1161337,4.151799,5.1874638,6.2231293,7.258794,8.294459,9.330124,10.622442,12.855859,15.089275,17.322693,19.55611,21.789526,24.022942,26.25636,28.489777,30.723192,32.95661,35.190025,37.423443,39.65686,41.890274,44.12369,46.35711,48.590527,50.82394,53.057358,55.290775,57.524193,59.757607,61.991024,64.22444,66.457855,68.69127,70.10669,71.1131,72.119514,73.12593,74.13235,73.59396,69.038994,64.48402,59.440792,-39.76085,-37.23103,-34.701214,-32.1714,-29.641584,-27.111767,-24.581951,-22.052135,-19.522316,-16.992504,-14.462685,-11.932873,-9.403053,-6.8732376,-4.3434258,-1.457852,-0.42218572,0.61348057,1.6491468,2.684813,3.720479,4.7561455,5.7918115,6.8274775,7.863144,8.89881,9.934477,10.970143,12.005809,13.041475,14.077142,14.599484,16.8329,19.066315,21.29973,23.533146,25.766562,27.999977,30.23339,32.46681,34.700222,36.93364,39.167053,41.400467,43.633884,45.867302,48.10071,50.33413,52.567543,54.80096,57.034378,59.26779,61.50121,63.32563,64.33205,65.33846,66.34488,67.351295,68.35771,69.364136,70.37055,71.37697,72.383385,75.86153,71.30655,66.75157,62.196598,-31.025461,-28.495644,-25.965826,-23.436008,-20.90619,-18.37637,-15.846554,-13.316734,-10.786919,-8.257099,-5.7272797,-3.197464,-0.6676445,1.8621712,3.2891617,4.3248277,5.3604937,6.39616,7.431826,8.467492,9.503159,10.538825,11.574491,12.610156,13.6458235,14.681489,15.7171545,16.752821,17.788486,18.824152,19.85982,20.895487,23.04335,25.276766,27.510181,29.743597,31.977013,34.210426,36.443844,38.677258,40.910675,43.14409,45.377502,47.61092,49.844337,52.07775,54.311165,56.544582,57.551,58.557415,59.56383,60.570248,61.576664,62.58308,63.589497,64.59592,65.60233,66.60875,67.615166,68.62158,69.628,70.634415,71.64083,72.64725,69.019196,64.464226,59.90925,-24.81986,-22.290045,-19.76023,-17.230413,-14.700598,-12.170784,-9.640968,-7.1111565,-4.581337,-2.051525,0.47829056,3.0081062,5.9648304,7.0004973,8.036164,9.071831,10.107498,11.143165,12.178831,13.2144985,14.250166,15.285831,16.321499,17.357166,18.392834,19.4285,20.464167,21.499834,22.5355,23.571167,24.606834,25.642502,27.02039,29.253805,31.48722,33.720634,35.954052,38.18747,40.420883,42.654297,44.887714,47.12113,49.76354,50.769955,51.77637,52.78279,53.789207,54.795624,55.80204,56.808456,57.814873,58.82129,59.827705,60.83412,61.840538,62.846954,63.85337,64.85979,65.8662,66.87262,67.879036,68.88545,69.89188,70.898285,71.28675,66.73179,62.17682,-16.084475,-13.554655,-11.024839,-8.49502,-5.9652023,-3.4353848,-0.90556717,1.6242485,4.154072,6.6838875,9.213703,10.711848,11.747514,12.78318,13.818846,14.854511,15.890178,16.925844,17.96151,18.997175,20.03284,21.068508,22.104172,23.13984,24.175505,25.21117,26.246838,27.282503,28.318169,29.353834,30.3895,31.425167,33.23081,35.464226,37.69764,39.931057,42.16447,43.988895,44.99531,46.001728,47.008144,48.01456,49.020977,50.027393,51.033813,52.04023,53.046646,54.053062,55.05948,56.065895,57.07231,58.078728,59.085144,60.09156,61.09798,62.104397,63.110813,64.11723,65.12365,66.130066,67.13648,68.1429,69.149315,70.15573,68.999405,64.44443,59.889454,-9.8788595,-7.349041,-4.819227,-2.2894115,0.24040604,2.7702217,5.3000374,7.829853,10.359669,13.387529,14.423196,15.458861,16.494528,17.530193,18.565859,19.601524,20.637192,21.672857,22.708523,23.74419,24.779856,25.815521,26.851189,27.886852,28.92252,29.958185,30.99385,32.02952,33.065186,34.10085,35.136517,36.17218,37.207848,38.214264,39.22068,40.227097,41.233517,42.239933,43.24635,44.252766,45.259182,46.265602,47.27202,48.278435,49.28485,50.291267,51.297684,52.3041,53.310516,54.316936,55.323353,56.32977,57.336185,58.342606,59.349022,60.35544,61.361855,62.36827,63.374687,64.3811,65.38753,66.393936,67.40036,68.40677,71.26696,66.71199,62.157017,-1.1434851,1.3863316,3.9161491,6.4459667,8.975782,11.505598,14.035416,16.565235,18.134531,19.170197,20.205862,21.24153,22.277195,23.31286,24.348526,25.384193,26.419859,27.455524,28.491192,29.526857,30.562523,31.598188,32.633854,33.66952,34.705185,35.740852,36.77652,37.703148,38.229965,38.756783,39.2836,39.810417,37.797306,37.74817,38.478138,39.484554,40.49097,41.497387,42.503803,43.51022,44.516636,45.523052,46.52947,47.535885,48.5423,49.548717,50.555138,51.561554,52.56797,53.574387,54.580803,55.58722,56.593636,57.60005,58.60647,59.612885,60.6193,61.625717,62.632133,63.63855,64.644966,65.65138,66.6578,67.664215,68.67063,64.42464,59.869667,5.062129,7.5919437,10.1217575,12.651573,15.181389,17.711203,20.810215,21.845882,22.881548,23.917215,24.95288,25.988548,27.024214,28.05988,29.095547,30.131212,31.166878,32.202545,33.238213,34.273876,35.309544,36.34521,37.380875,38.198463,38.725277,39.25209,39.778908,40.30572,40.83254,41.359352,41.88617,42.96534,38.435898,38.386765,38.337627,38.28849,38.742004,39.74842,40.754837,41.761253,42.76767,43.77409,44.780506,45.786922,46.79334,47.799755,48.80617,49.812588,50.819008,51.825424,52.83184,53.838257,54.844673,55.85109,56.857506,57.863922,58.87034,59.87676,60.88317,61.88959,62.89601,63.902424,64.908844,65.91526,66.92168,66.69219,62.13722,13.797519,16.32734,18.857159,21.386978,23.916798,25.557228,26.592894,27.62856,28.664225,29.69989,30.735556,31.771221,32.806885,33.842552,34.87822,35.913883,36.949547,37.985214,38.693764,39.22058,39.747395,40.27421,40.801025,41.327843,41.85466,42.381474,42.90829,43.435104,43.96192,44.48874,45.015553,42.28335,39.02536,38.976223,38.927086,38.87795,38.828815,39.00586,40.01228,41.018696,42.025112,43.03153,44.037945,45.044365,46.05078,47.057198,48.063614,49.07003,50.076447,51.082863,52.089283,53.0957,54.102116,55.108532,56.114952,57.12137,58.127785,59.1342,60.140617,61.147034,62.15345,63.159866,64.16628,65.1727,66.17912,64.40484,59.84987,20.003113,22.532925,25.062737,28.232899,29.268566,30.304232,31.3399,32.375565,33.411232,34.4469,35.482567,36.518234,37.5539,38.66226,39.18907,39.71589,40.242702,40.76952,41.296333,41.82315,42.349964,42.87678,43.403595,43.930412,44.457226,44.984043,45.510857,46.037674,46.564487,47.091305,48.72283,45.16211,41.60139,39.61482,39.56568,39.516544,39.467407,39.41827,39.369133,39.26973,40.276146,41.282562,42.28898,43.295395,44.30181,45.308228,46.314644,47.32106,48.32748,49.333897,50.340313,51.34673,52.353146,53.359562,54.36598,55.372395,56.378815,57.38523,58.391647,59.398064,60.40448,61.410896,62.417313,63.42373,64.430145,66.67246,62.117493,28.738506,31.268326,32.97991,34.015575,35.051243,36.086906,37.122574,38.158237,39.15756,39.684376,40.21119,40.738007,41.26482,41.791634,42.31845,42.845264,43.37208,43.898895,44.425713,44.952526,45.479343,46.006157,46.532974,47.059788,47.586605,48.11342,48.640236,49.16705,49.693867,50.22068,48.040894,44.480145,40.91939,40.204273,40.155136,40.106003,40.056866,40.00773,39.95859,39.90946,39.86032,40.540016,41.546436,42.552853,43.55927,44.565685,45.5721,46.578518,47.584934,48.591354,49.59777,50.604187,51.610603,52.61702,53.623436,54.629852,55.63627,56.642685,57.6491,58.65552,59.661938,60.668354,61.67477,62.68119,63.687607,64.38505,59.830074,35.655582,36.691254,37.72692,38.762592,39.65287,40.179688,40.7065,41.23332,41.76013,42.286945,42.813763,43.340576,43.867393,44.394207,44.92102,45.447838,45.97465,46.501465,47.028282,47.555096,48.081913,48.608727,49.135544,49.662357,50.18917,50.71599,51.2428,51.769615,52.296432,54.480385,50.919647,47.35891,43.798176,40.84287,40.79373,40.7446,40.69546,40.646324,40.597187,40.54805,40.498913,40.449776,40.40064,40.803886,41.810303,42.81672,43.823135,44.82955,45.835968,46.842384,47.8488,48.855217,49.861633,50.86805,51.87447,52.880886,53.887302,54.89372,55.900135,56.90655,57.912968,58.919384,59.925804,60.93222,61.938637,62.945053,62.0977,40.674988,41.201805,41.72862,42.255436,42.78225,43.309067,43.83588,44.362694,44.88951,45.416325,45.943142,46.469955,46.996773,47.523586,48.050404,48.577217,49.104034,49.630848,50.15766,50.68448,51.211296,51.73811,52.264923,52.79174,53.318554,53.84537,54.372185,54.899002,55.425816,53.798393,50.23765,46.67691,43.116173,41.432327,41.383194,41.334057,41.28492,41.235783,41.186646,41.13751,41.08837,41.039238,40.9901,40.940964,41.067757,42.074173,43.080593,44.08701,45.093426,46.099842,47.10626,48.112675,49.11909,50.12551,51.131927,52.138344,53.14476,54.151176,55.157593,56.16401,57.170425,58.17684,59.183258,60.189674,61.196095,62.202507,59.810284,43.27755,43.804367,44.33118,44.857998,45.38481,45.91163,46.438442,46.96526,47.492073,48.01889,48.545704,49.07252,49.599335,50.126152,50.652966,51.179783,51.706596,52.233414,52.760227,53.287045,53.813858,54.340675,54.86749,55.394306,55.92112,56.447937,56.97475,57.501568,58.02838,56.677143,53.116413,49.55568,45.99495,42.070927,42.02179,41.972652,41.923515,41.87438,41.82524,41.776108,41.72697,41.677834,41.628696,41.57956,41.530426,41.48129,41.331615,42.33803,43.344448,44.350864,45.35728,46.3637,47.370117,48.376534,49.38295,50.389366,51.395782,52.402203,53.40862,54.415035,55.42145,56.427868,57.434288,58.440704,59.44712,60.453537,62.077904,46.406937,46.933754,47.460567,47.987385,48.5142,49.041016,49.56783,50.094646,50.62146,51.148273,51.67509,52.201904,52.72872,53.255535,53.782352,54.309166,54.835983,55.362797,55.88961,56.416428,56.94324,57.47006,57.996872,58.52369,59.050503,59.577316,60.104134,60.630947,59.555885,55.99515,52.434414,48.87368,45.312943,42.66038,42.611244,42.562107,42.51297,42.463833,42.4147,42.365562,42.316425,42.26729,42.21815,42.169018,42.11988,42.070744,42.021606,41.97247,42.6019,43.60832,44.614735,45.62115,46.62757,47.633987,48.640404,49.64682,50.65324,51.659657,52.666073,53.672493,54.67891,55.685326,56.691742,57.698162,58.704575,59.710995,59.790485,52.288696,49.536316,50.06313,50.589947,51.11676,51.643578,52.170395,52.69721,53.224026,53.75084,54.277657,54.80447,55.331287,55.8581,56.38492,56.911736,57.43855,57.965366,58.49218,59.018997,59.545815,60.072628,60.59944,61.12626,61.653076,62.17989,62.706707,63.23352,62.43464,58.873898,55.313156,51.75242,48.191677,43.298977,43.24984,43.200703,43.151566,43.102432,43.053295,43.004158,42.95502,42.905884,42.856747,42.807613,42.758476,42.70934,42.660202,42.611065,42.56193,42.512794,42.865772,43.87219,44.878605,45.88502,46.891438,47.897854,48.90427,49.91069,50.917107,51.923523,52.92994,53.936356,54.942772,55.94919,56.955605,57.96202,58.968437,55.730373,52.665703,53.19252,53.719334,54.24615,54.772964,55.29978,55.826595,56.353413,56.880226,57.407043,57.933857,58.460674,58.987488,59.514305,60.04112,60.567932,61.09475,61.621567,62.14838,62.675194,63.20201,63.72883,64.25564,64.782455,65.30927,65.83609,65.313385,61.75265,58.191917,54.631184,51.07045,47.50972,43.948982,43.8393,43.79016,43.741028,43.69189,43.642754,43.593616,43.54448,43.495342,43.446205,43.397068,43.347935,43.298798,43.24966,43.200523,43.151386,43.10225,43.053112,43.12964,44.13606,45.142475,46.14889,47.15531,48.161728,49.168144,50.17456,51.18098,52.187397,53.193813,54.200233,55.20665,56.213066,57.219482,58.2259,63.329765,59.172035,55.79509,56.321903,56.84872,57.375534,57.902348,58.429165,58.95598,59.482796,60.00961,60.536427,61.06324,61.590057,62.11687,62.643684,63.1705,63.697315,64.22413,64.750946,65.27776,65.80458,66.33139,66.85821,67.385025,67.911835,68.43865,68.19213,64.63139,61.070656,57.50992,53.949184,50.388447,46.82771,44.47789,44.428753,44.37962,44.330482,44.281345,44.23221,44.18307,44.133938,44.0848,44.035664,43.986526,43.93739,43.888256,43.83912,43.78998,43.740845,43.691708,43.642574,43.593437,43.393513,44.39993,45.406345,46.41276,47.419178,48.425594,49.43201,50.438427,51.444847,52.451263,53.45768,54.464096,55.470512,56.47693,66.771416,62.6137,58.924473,59.451286,59.978104,60.504917,61.031734,61.558548,62.085365,62.612183,63.138996,63.66581,64.19263,64.719444,65.246254,65.77307,66.29989,66.826706,67.353516,67.88033,68.40715,68.93397,69.460785,69.987595,70.51441,71.04123,71.070885,67.51015,63.949417,60.388687,56.827953,53.26722,49.70649,46.145756,45.067352,45.018215,44.969078,44.91994,44.870804,44.821667,44.77253,44.723396,44.67426,44.625122,44.575985,44.526848,44.47771,44.428577,44.37944,44.330303,44.281166,44.23203,44.18289,44.133755,44.08462,44.663795,45.67021,46.67663,47.683044,48.68946,49.695877,50.702293,51.70871,52.715126,53.721542,54.727955,55.73437,74.37088,70.21314,66.055405,62.053852,62.58067,63.107483,63.6343,64.16112,64.68793,65.214745,65.74156,66.26837,66.79519,67.32201,67.848816,68.37563,68.90245,69.42927,69.95608,70.482895,71.00971,71.53653,72.06334,72.59016,73.116974,73.64378,73.949684,70.38894,66.8282,63.267456,59.70672,56.145977,52.585236,49.024494,45.705948,45.65681,45.607674,45.558537,45.5094,45.460262,45.41113,45.36199,45.312855,45.263718,45.21458,45.165443,45.11631,45.067173,45.018036,44.9689,44.91976,44.870625,44.82149,44.772354,44.723217,44.67408,44.624943,44.927654,45.93407,46.94049,47.946907,48.953323,49.959743,50.96616,51.972576,52.978996,53.985413,77.81253,73.65482,69.497116,65.33941,65.710045,66.236855,66.76367,67.29049,67.81731,68.34412,68.87093,69.39775,69.92457,70.45138,70.978195,71.50501,72.03183,72.55864,73.08546,73.612274,74.13909,74.66591,75.19272,75.719536,76.24635,76.77316,73.26769,69.706955,66.14622,62.58548,59.024742,55.464005,51.903267,48.342533,46.295403,46.246265,46.19713,46.147995,46.098858,46.04972,46.000584,45.951447,45.902313,45.853176,45.80404,45.7549,45.705765,45.65663,45.607494,45.558357,45.50922,45.460087,45.41095,45.361813,45.312675,45.26354,45.214405,45.165268,45.191525,46.19794,47.204357,48.210773,49.21719,50.223606,51.230026,52.236443,53.24286,85.412,81.25427,77.09655,72.93882,68.31261,68.839424,69.36624,69.89306,70.419876,70.946686,71.4735,72.00032,72.52714,73.053955,73.580765,74.10758,74.6344,75.16122,75.688034,76.21484,76.74166,77.26848,77.795296,78.32211,78.84892,79.707184,76.14644,72.5857,69.02496,65.464226,61.903484,58.342743,54.782005,51.221268,46.934,46.88486,46.835724,46.786587,46.737453,46.688316,46.63918,46.590042,46.540905,46.49177,46.442635,46.393497,46.34436,46.295223,46.246086,46.196953,46.147816,46.09868,46.04954,46.000404,45.951267,45.902134,45.852997,45.80386,45.754723,45.705585,45.455395,46.46181,47.468227,48.474644,49.481064,50.48748,51.493896,88.853645,84.69592,80.53821,76.38049,72.22278,71.96881,72.49563,73.02244,73.549255,74.07607,74.60289,75.1297,75.65652,76.183334,76.710144,77.23696,77.76378,78.290596,78.817406,79.34422,79.87104,80.39785,80.92467,81.451485,81.9783,79.025185,75.46445,71.90372,68.34298,64.78225,61.22151,57.660778,54.100044,50.539307,47.523457,47.47432,47.425186,47.37605,47.326912,47.277775,47.228638,47.179504,47.130367,47.08123,47.032093,46.982956,46.93382,46.884686,46.83555,46.78641,46.737274,46.688137,46.639,46.589867,46.54073,46.491592,46.442455,46.39332,46.344185,46.295048,46.24591,46.196774,46.72568,47.732098,48.738514,49.74493,50.751343,96.452995,92.29529,88.13758,83.97987,79.82216,74.57138,75.0982,75.62501,76.151825,76.67864,77.20546,77.73227,78.25909,78.785904,79.31272,79.83953,80.36635,80.893166,81.41998,81.94679,82.47361,83.00043,83.527245,84.054054,85.46467,81.90393,78.3432,74.78246,71.221725,67.66099,64.10025,60.539513,56.978775,53.418037,48.16205,48.11291,48.063778,48.01464,47.965504,47.916367,47.86723,47.818096,47.76896,47.719822,47.670685,47.621548,47.57241,47.523277,47.47414,47.425003,47.375866,47.32673,47.277596,47.22846,47.17932,47.130184,47.081047,47.03191,46.982777,46.93364,46.884502,46.835365,46.78623,46.73709,46.98955,47.995968,49.002384,99.89475,95.73703,91.57931,87.421585,83.26386,79.10614,78.22758,78.754395,79.28121,79.80802,80.33484,80.86166,81.38847,81.91528,82.4421,82.96892,83.49573,84.022545,84.54936,85.07618,85.60299,86.12981,86.656624,87.18344,84.782684,81.22195,77.66122,74.10048,70.53975,66.97902,63.41828,59.85755,56.296814,52.736084,49.17535,48.702374,48.653236,48.6041,48.554962,48.50583,48.45669,48.407555,48.358418,48.30928,48.260147,48.21101,48.161873,48.112736,48.0636,48.01446,47.96533,47.91619,47.867054,47.817917,47.76878,47.719646,47.67051,47.621372,47.572235,47.523098,47.47396,47.424828,47.37569,47.326553,47.277416,47.253407,48.259827,107.4941,103.33639,99.17867,95.020966,90.86325,86.705536,80.83015,81.356964,81.88378,82.41059,82.93741,83.464226,83.991035,84.51785,85.04467,85.57149,86.0983,86.625114,87.15193,87.67874,88.20556,88.732376,89.259186,91.22216,87.66142,84.10069,80.539955,76.97922,73.41849,69.85775,66.29702,62.736282,59.17555,55.61481,52.054077,49.34097,49.291832,49.242695,49.193558,49.144424,49.095287,49.04615,48.997013,48.947876,48.898743,48.849606,48.80047,48.75133,48.702194,48.65306,48.603924,48.554787,48.50565,48.456512,48.407375,48.358242,48.309105,48.259968,48.21083,48.161694,48.11256,48.063423,48.014286,47.96515,47.91601,47.866875,47.81774,110.935745,106.77804,102.62032,98.462616,94.30491,90.1472,85.98949,84.48634,85.01315,85.53997,86.06679,86.593605,87.12042,87.64723,88.17405,88.70087,89.227684,89.7545,90.28131,90.80813,91.334946,91.86176,92.38858,90.54018,86.97944,83.4187,79.85796,76.297226,72.736496,69.17575,65.61502,62.054283,58.49354,54.932804,51.372066,49.930424,49.881287,49.83215,49.783016,49.73388,49.684742,49.635605,49.586468,49.537334,49.488197,49.43906,49.389923,49.340786,49.291653,49.242516,49.19338,49.14424,49.095104,49.045967,48.996834,48.947697,48.89856,48.849422,48.800285,48.751152,48.702015,48.652878,48.60374,48.554604,48.50547,48.456333,48.407196]
+ examples/rasterize/rasterize-test4.txt view
@@ -0,0 +1,4 @@+[((-267,-201),33.957397),((-226,-217),36.21704),((-244,-303),166.1195),((-343,-316),15.7873535),((-280,-273),39.814148),((-306,-342),27.929932),((-324,-236),79.39956),((-305,-213),43.06239),((-335,-252),121.0145),((-330,-297),15.217541),((-294,-311),19.864101),((-332,-271),140.75253),((-336,-285),167.71878),((-319,-285),68.29455),((-318,-277),66.3733),((-235,-275),136.13342),((-246,-339),96.01575)]+[(11,12,14),(4,0,7),(4,7,6),(6,14,4),(14,13,4),(14,12,13),(13,12,9),(14,8,11),(6,8,14),(4,1,0),(15,1,4),(2,15,4),(10,2,4),(13,10,4),(9,10,13),(3,10,9),(3,5,10),(5,10,16),(10,2,16)]+((-321,-321),(-255,-255))+[19.671001,19.366583,19.062164,18.757746,18.453327,18.14891,17.844492,17.593893,17.500454,17.407015,17.313576,17.220135,17.126696,17.033257,16.939817,16.846378,16.75294,16.659498,16.56606,16.47262,16.37918,19.552664,22.726147,25.899628,29.07311,32.246593,35.420074,38.59356,41.76704,44.940525,48.114006,51.287487,54.46097,57.634453,65.31526,75.09943,80.23697,80.727875,81.21878,81.70969,82.20059,82.6915,83.1824,82.961136,82.59746,81.88012,79.86614,77.852165,75.99871,75.80419,75.60967,75.41515,75.220634,75.02612,74.831604,74.637085,74.442566,74.248055,74.053535,73.85902,73.6645,73.46998,73.27547,73.08095,72.88643,73.098595,73.31075,19.93747,19.63305,19.328632,19.024214,18.719795,18.415377,18.110958,17.733347,17.639906,17.546467,17.453028,17.359589,17.26615,17.17271,17.07927,16.98583,16.892391,16.798952,16.705513,16.612074,16.155632,19.329115,22.502598,25.676079,28.849564,32.023045,35.19653,38.37001,41.543495,44.716976,47.890457,51.063942,54.237427,57.410908,60.58439,64.358864,74.143036,74.63394,75.12485,75.615746,76.10665,76.59756,77.08846,77.674324,77.31064,76.7112,74.69719,72.79024,72.59572,72.4012,72.20668,72.01217,71.81765,71.62313,71.42861,71.2341,71.03958,70.84506,70.78611,70.998276,71.210434,71.4226,71.634766,71.846924,72.05909,72.271255,72.48342,19.899525,19.595106,19.290688,18.986269,18.68185,18.377432,18.073013,17.77936,17.68592,17.592482,17.499043,17.405603,17.312164,17.218725,17.125284,17.031845,16.938406,16.844967,16.751528,16.658089,19.105566,22.279049,25.452532,28.626015,31.799498,34.97298,38.14646,41.319946,44.49343,47.666912,50.840393,54.013878,57.187363,60.36084,63.534325,66.70781,68.54,69.03091,69.52181,70.01272,70.503624,70.99452,71.48543,71.97633,71.54222,69.581764,69.387245,69.19273,68.998215,68.803696,68.609184,68.68578,68.89795,69.11011,69.32227,69.53444,69.7466,69.95876,70.17093,70.383095,70.59525,70.80742,71.019585,71.23175,71.44391,71.656075,71.86824,20.165998,19.86158,19.557161,19.252743,18.948324,18.643906,18.339487,18.035069,17.825375,17.731936,17.638496,17.545057,17.451616,17.358177,17.264738,17.171299,17.07786,16.98442,16.89098,15.708533,18.882019,22.055504,25.228989,28.402473,31.575958,34.749443,37.922928,41.096413,44.269897,47.443382,50.616867,53.79036,56.963837,60.13732,63.310806,66.39316,67.611916,67.457085,67.30226,67.14743,66.99261,66.837776,66.68295,66.52812,66.3733,66.585464,66.79762,67.00979,67.221954,67.43412,67.64628,67.858444,68.07061,68.282776,68.494934,68.7071,68.919266,69.131424,69.34359,69.555756,69.76792,69.98008,70.192245,70.40441,70.61658,70.828735,71.0409,20.128054,19.823635,19.519217,19.214798,18.91038,18.60596,18.301544,17.997124,17.87139,17.77795,17.684511,17.591072,17.497631,17.404192,17.310753,17.217314,17.123875,17.030436,16.936996,18.658468,21.83195,25.005432,28.178913,31.352394,34.525875,37.699356,40.872837,44.046318,47.219803,50.393284,53.56676,56.740246,59.913727,63.087208,64.93953,65.835106,66.730675,66.69705,66.54223,66.3874,66.23257,66.07774,65.92291,65.76809,65.758125,65.97029,66.18246,66.39462,66.60678,66.81895,67.03111,67.24327,67.45544,67.6676,67.87976,68.09193,68.30409,68.51626,68.72842,68.94058,69.15275,69.364914,69.57707,69.78924,70.0014,70.21356,70.42573,20.394522,20.090103,19.785685,19.481266,19.176847,18.872429,18.56801,18.263592,18.010841,17.917402,17.823963,17.730524,17.637083,17.543644,17.450205,17.356764,17.263325,17.169886,17.076447,18.435013,21.60849,24.781967,27.955444,31.128923,34.3024,37.47588,40.649353,43.822834,46.996307,50.16979,53.343266,56.516743,59.69022,62.59036,63.48593,64.3815,65.27708,66.091835,65.937004,65.78218,65.62735,65.47253,65.317696,65.16287,64.93078,65.142944,65.35511,65.56727,65.779434,65.9916,66.203766,66.415924,66.62809,66.840256,67.052414,67.26458,67.476746,67.68891,67.90107,68.113235,68.3254,68.53757,68.749725,68.96189,69.17406,69.386215,69.59838,20.356575,20.052156,19.747738,19.44332,19.1389,18.834482,18.530064,18.225647,18.056856,17.963417,17.869978,17.776537,17.683098,17.589659,17.49622,17.402779,17.30934,17.2159,18.211468,21.384947,24.558426,27.731907,30.905386,34.078865,37.252346,40.425827,43.599304,46.772785,49.946266,53.119743,56.29322,59.466705,61.136753,62.032322,62.92789,63.823456,64.719025,65.331795,65.17697,65.02214,64.86731,64.71249,64.557655,64.402824,64.3156,64.52776,64.73993,64.952095,65.16425,65.37642,65.588585,65.80075,66.01291,66.225075,66.43724,66.64941,66.861565,67.07373,67.2859,67.49806,67.71022,67.922386,68.13455,68.34672,68.558876,68.77104,68.98321,20.623047,20.31863,20.014212,19.709793,19.405375,19.100956,18.796537,18.492119,18.19631,18.10287,18.009432,17.91599,17.822552,17.729113,17.635672,17.542233,17.448793,17.355352,17.987919,21.161402,24.334885,27.508368,30.68185,33.85533,37.028816,40.2023,43.375782,46.549267,49.722748,52.896233,56.06971,58.787582,59.68315,60.57872,61.47429,62.369854,63.265423,64.16099,64.571754,64.41692,64.2621,64.10727,63.952442,63.797615,63.488266,63.70043,63.912594,64.124756,64.33692,64.54909,64.761246,64.97341,65.18558,65.39774,65.6099,65.82207,66.03423,66.2464,66.45856,66.67072,66.88289,67.09505,67.30721,67.51938,67.731544,67.9437,68.15587,20.585096,20.280678,19.97626,19.67184,19.367422,19.063004,18.758585,18.454166,18.242321,18.148882,18.055443,17.962004,17.868565,17.775126,17.681686,17.588247,17.494808,17.76437,20.937847,24.111326,27.284805,30.458282,33.63176,36.805237,39.978718,43.152195,46.325672,49.49915,52.67263,55.846107,57.333954,58.229523,59.12509,60.02066,60.91623,61.8118,62.707367,63.602936,63.811714,63.656887,63.50206,63.347233,63.1924,63.037575,62.882748,63.085255,63.29742,63.509583,63.72175,63.93391,64.14607,64.35824,64.570404,64.78256,64.99473,65.206894,65.41905,65.63122,65.84338,66.05555,66.26771,66.47987,66.69204,66.9042,67.11636,67.32853,67.540695,20.85157,20.547152,20.242733,19.938314,19.633896,19.329477,19.025059,18.72064,18.381775,18.288336,18.194897,18.101458,18.008018,17.91458,17.821138,17.7277,17.63426,17.540821,20.714302,23.887783,27.061264,30.234745,33.408226,36.581707,39.755188,42.928673,46.10215,49.275635,52.449116,54.984783,55.880352,56.77592,57.67149,58.567062,59.46263,60.3582,61.25377,62.149338,63.2065,63.051674,62.896847,62.74202,62.587193,62.432365,62.277534,62.25791,62.470074,62.68224,62.8944,63.106567,63.31873,63.530895,63.743057,63.955223,64.16739,64.37955,64.59171,64.80388,65.016045,65.2282,65.44037,65.652534,65.8647,66.07686,66.289024,66.50119,66.71335,20.813625,20.509207,20.204788,19.90037,19.595951,19.291534,18.987114,18.682697,18.42779,18.33435,18.240911,18.147472,18.054031,17.960592,17.867153,17.773714,17.680273,20.490755,23.664242,26.837727,30.011211,33.184692,36.358177,39.531662,42.705147,45.87863,49.052116,52.2256,53.531178,54.426746,55.32231,56.21788,57.11345,58.009014,58.904583,59.800148,60.695717,61.591286,62.44646,62.291634,62.136806,61.98198,61.82715,61.67232,61.517494,61.64274,61.8549,62.067066,62.27923,62.491394,62.703556,62.91572,63.127884,63.34005,63.55221,63.764378,63.97654,64.188705,64.40087,64.61303,64.825195,65.03736,65.24953,65.461685,65.67385,65.88602,66.098175,21.080093,20.775675,20.471256,20.166838,19.86242,19.558,19.253582,18.949163,18.567244,18.473804,18.380363,18.286924,18.193485,18.100046,18.006607,17.913168,17.093725,20.267204,23.440681,26.614162,29.78764,32.96112,36.134598,39.308075,42.48156,45.655037,48.828514,51.18198,52.077553,52.97312,53.86869,54.764263,55.659832,56.5554,57.450974,58.346542,59.24211,60.137684,61.033253,61.68642,61.53159,61.376762,61.221935,61.06711,60.91228,60.8154,61.02756,61.239727,61.45189,61.664055,61.876217,62.08838,62.300545,62.512707,62.724873,62.937035,63.149197,63.361362,63.573524,63.78569,63.997852,64.210014,64.42218,64.634346,64.846504,65.05867,65.270836,21.042147,20.737728,20.43331,20.128891,19.824474,19.520054,19.215637,18.911217,18.613256,18.519817,18.426378,18.33294,18.2395,18.14606,18.05262,17.95918,20.043657,23.21714,26.390623,29.564106,32.737587,35.91107,39.084557,42.258038,45.43152,48.605003,49.72838,50.623947,51.519512,52.41508,53.31065,54.20622,55.101788,55.997356,56.892925,57.78849,58.68406,59.579628,60.475197,60.92638,60.771553,60.616722,60.461895,60.307064,60.152237,60.200226,60.412388,60.62455,60.836716,61.048878,61.261044,61.473206,61.68537,61.897533,62.109695,62.32186,62.534023,62.74619,62.95835,63.170517,63.38268,63.59484,63.807007,64.01917,64.23133,64.4435,64.65566,21.308619,21.004202,20.699783,20.395365,20.090946,19.786528,19.48211,19.177692,18.873272,18.659271,18.565832,18.472393,18.378954,18.285515,18.192076,16.646624,19.820112,22.993599,26.167086,29.340572,32.51406,35.687546,38.86103,42.034523,45.208008,47.379204,48.274773,49.17034,50.06591,50.96148,51.857048,52.752617,53.648186,54.543755,55.439323,56.334892,57.23046,58.12603,59.0216,60.321163,60.166336,60.01151,59.85668,59.701855,59.547028,59.37288,59.585045,59.797207,60.009373,60.221535,60.4337,60.645863,60.85803,61.07019,61.282356,61.49452,61.706684,61.918846,62.131012,62.343174,62.55534,62.7675,62.979668,63.19183,63.403996,63.616158,63.828323,21.270668,20.96625,20.66183,20.357412,20.052994,19.748575,19.444157,19.139738,18.83532,18.705284,18.611843,18.518404,18.424965,18.331526,18.238087,19.596655,22.770136,25.943617,29.117096,32.290577,35.464058,38.63754,41.81102,44.9845,45.925602,46.821167,47.716736,48.612305,49.50787,50.40344,51.299004,52.194572,53.09014,53.98571,54.881275,55.776844,56.67241,57.567978,58.463547,59.35911,59.4063,59.25147,59.09664,58.941814,58.786983,58.757706,58.969868,59.182034,59.394196,59.60636,59.818523,60.030685,60.24285,60.455013,60.66718,60.87934,61.091507,61.30367,61.51583,61.727997,61.94016,62.152325,62.364487,62.576653,62.788815,63.00098,63.213142,21.537144,21.232725,20.928307,20.623888,20.31947,20.01505,19.710632,19.406214,19.101795,18.84474,18.751299,18.65786,18.56442,18.47098,18.37754,19.373104,22.546577,25.72005,28.893524,32.066998,35.24047,38.41394,42.680836,43.576405,44.471973,45.367542,46.26311,47.15868,48.05425,48.949818,49.845387,50.740955,51.636528,52.532097,53.427666,54.323235,55.218803,56.114372,57.00994,57.90551,58.80108,58.64625,58.491425,58.336597,58.18177,57.930367,58.142532,58.354694,58.566856,58.779022,58.991184,59.20335,59.415512,59.627678,59.83984,60.052006,60.264168,60.476334,60.688496,60.900658,61.112823,61.324986,61.53715,61.749313,61.96148,62.17364,62.385807,21.499199,21.19478,20.890362,20.585943,20.281525,19.977106,19.672688,19.368269,19.06385,18.890753,18.797314,18.703873,18.610434,18.516994,19.149557,22.323034,25.496513,28.66999,31.843468,35.016945,38.190422,41.227234,42.122803,43.01837,43.91394,44.80951,45.70508,46.60065,47.49622,48.39179,49.287357,50.182926,51.0785,51.974068,52.869637,53.765205,54.660774,55.556343,56.451912,57.347485,58.04104,57.88621,57.731384,57.576557,57.421726,57.315193,57.527355,57.73952,57.951683,58.16385,58.37601,58.588173,58.80034,59.0125,59.224667,59.43683,59.648994,59.861156,60.07332,60.285484,60.497646,60.709812,60.921974,61.13414,61.346302,61.558464,61.77063,21.765663,21.461245,21.156826,20.852407,20.547989,20.243572,19.939152,19.634735,19.330315,19.030205,18.936766,18.843327,18.749887,18.656448,18.92601,22.099493,25.272976,28.446457,31.61994,34.793423,38.878056,39.773624,40.669193,41.564762,42.46033,43.3559,44.25147,45.147038,46.042606,46.938175,47.833744,48.72931,49.624878,50.520447,51.416016,52.311584,53.207153,54.102722,54.99829,55.89386,56.78943,57.281002,57.12617,56.971344,56.816517,56.487846,56.700012,56.912174,57.12434,57.336502,57.548668,57.76083,57.972992,58.185158,58.39732,58.609486,58.821648,59.033813,59.245975,59.458138,59.670303,59.882465,60.09463,60.306793,60.51896,60.73112,60.943283,21.727718,21.423302,21.118881,20.814465,20.510044,20.205627,19.901207,19.59679,19.29237,19.07622,18.982779,18.88934,18.7959,18.702461,21.875952,25.04944,28.22293,31.39642,34.56991,37.424458,38.320026,39.215595,40.111164,41.006733,41.9023,42.79787,43.69344,44.58901,45.484573,46.380142,47.27571,48.17128,49.06685,49.962418,50.857986,51.753555,52.649124,53.544693,54.44026,55.33583,56.2314,56.520958,56.36613,56.211304,56.056473,55.901646,56.08484,56.297,56.509163,56.72133,56.93349,57.145657,57.35782,57.569984,57.782146,57.994312,58.206474,58.41864,58.630802,58.842964,59.05513,59.267292,59.479458,59.69162,59.903786,60.115948,60.328114,21.994194,21.689775,21.385357,21.080938,20.77652,20.472101,20.167683,19.863264,19.558846,19.215673,19.122232,19.028793,18.935354,18.478912,21.652391,24.82587,27.999352,31.172829,35.07526,35.970825,36.866394,37.761963,38.65753,39.5531,40.44867,41.34424,42.239807,43.135376,44.030945,44.926514,45.822083,46.71765,47.61322,48.50879,49.404358,50.299927,51.195496,52.091064,52.986633,53.882202,54.77777,55.91574,55.760914,55.606087,55.45126,55.296432,55.2575,55.46966,55.681828,55.89399,56.10615,56.318317,56.53048,56.742645,56.954807,57.166973,57.379135,57.5913,57.803463,58.015625,58.22779,58.439953,58.65212,58.86428,59.076443,59.28861,59.50077,21.95624,21.651821,21.347404,21.042984,20.738567,20.434149,20.12973,19.825312,19.520893,19.261686,19.168247,19.074808,18.981369,21.42885,24.602337,27.775822,30.94931,33.62165,34.51722,35.41279,36.30836,37.20393,38.0995,38.995068,39.890636,40.786205,41.681774,42.577343,43.47291,44.368484,45.264053,46.159622,47.05519,47.95076,48.84633,49.741898,50.637466,51.533035,52.428604,53.324173,54.21974,55.115314,55.000874,54.846046,54.69122,54.53639,54.642323,54.85449,55.06665,55.278816,55.49098,55.70314,55.915306,56.12747,56.339634,56.551796,56.763958,56.976124,57.188286,57.40045,57.612614,57.824776,58.03694,58.249104,58.461266,58.67343,58.29202,22.222715,21.918297,21.613878,21.30946,21.005041,20.700623,20.396204,20.091785,19.787367,19.40114,19.307701,19.21426,18.031809,21.205307,24.378803,27.552301,31.27248,32.16805,33.063618,33.959183,34.85475,35.75032,36.64589,37.54146,38.437027,39.332596,40.22816,41.12373,42.0193,42.914867,43.810432,44.706,45.60157,46.49714,47.392708,48.288277,49.183846,50.079414,50.97498,51.870552,52.766117,53.661686,54.39566,54.240833,54.086006,53.93118,53.81498,54.027145,54.239307,54.451473,54.663635,54.8758,55.087963,55.30013,55.51229,55.724457,55.93662,56.148785,56.360947,56.573112,56.785275,56.99744,57.209602,57.42177,57.63393,57.71775,57.22404,22.18477,21.880352,21.575933,21.271515,20.967096,20.662678,20.35826,20.05384,19.749422,19.447155,19.353716,19.260277,20.981749,24.155231,27.328712,29.81885,30.71442,31.60999,32.505558,33.401127,34.296696,35.192265,36.087837,36.983406,37.878975,38.774544,39.670113,40.56568,41.46125,42.356823,43.25239,44.14796,45.04353,45.939102,46.83467,47.73024,48.62581,49.521378,50.416946,51.312515,52.208084,53.103653,53.635616,53.48079,53.325962,53.171135,53.199806,53.41197,53.624134,53.836296,54.048462,54.260624,54.47279,54.68495,54.897118,55.10928,55.32144,55.533607,55.74577,55.957935,56.170097,56.382263,56.594425,56.80659,56.64977,56.15606,55.66235,22.451235,22.146816,21.842398,21.53798,21.23356,20.929142,20.624723,20.320305,20.015886,19.711468,19.493166,19.399727,20.758286,23.931747,27.469679,28.365246,29.260815,30.156384,31.051952,31.947521,32.84309,33.73866,34.634228,35.529797,36.425365,37.32093,38.2165,39.11207,40.007637,40.903206,41.798775,42.694344,43.589912,44.48548,45.38105,46.27662,47.172188,48.067757,48.963326,49.858894,50.754463,51.65003,53.030407,52.87558,52.72075,52.56592,52.372467,52.58463,52.796795,53.008957,53.221123,53.433285,53.64545,53.857613,54.069775,54.28194,54.494102,54.70627,54.91843,55.130596,55.34276,55.554924,55.767086,56.075497,55.581787,55.088078,54.594368,23.12876,22.4155,21.804455,21.500036,21.195618,20.8912,20.58678,20.282362,19.977943,19.673525,19.53918,20.534744,23.708218,26.016075,26.911644,27.807213,28.702782,29.59835,30.49392,31.389488,32.285057,33.180626,34.076195,34.971764,35.867332,36.7629,37.65847,38.55404,39.449608,40.345177,41.240746,42.136314,43.031883,43.927452,44.82302,45.71859,46.61416,47.509727,48.405296,49.300865,50.196434,51.092003,51.98757,52.11554,51.960712,51.805885,51.757286,51.96945,52.181614,52.39378,52.60594,52.818108,53.03027,53.242435,53.4546,53.666763,53.87893,54.09109,54.303257,54.51542,54.727585,54.93975,55.00752,54.51381,54.0201,53.52639,53.03268,24.655819,23.942562,23.229305,22.51605,21.802794,21.157673,20.853254,20.548836,20.244417,19.94,19.678635,20.311203,23.666903,24.562471,25.45804,26.353607,27.249176,28.144743,29.040312,29.935879,30.831448,31.727016,32.622585,33.51815,34.41372,35.309288,36.204857,37.100426,37.99599,38.89156,39.78713,40.682693,41.578262,42.47383,43.3694,44.26497,45.160538,46.056107,46.951675,47.84724,48.742805,49.638374,50.533943,51.510326,51.355495,51.20067,50.929947,51.142113,51.354275,51.56644,51.778603,51.990765,52.20293,52.415092,52.62726,52.83942,53.051582,53.26375,53.47591,53.688076,53.900238,54.433266,53.939552,53.445843,52.952133,52.458424,51.96471,25.4696,24.756346,24.043089,23.329834,22.616577,21.90332,21.190065,20.510881,20.206463,19.902046,20.087645,22.213274,23.108843,24.004412,24.89998,25.79555,26.69112,27.586689,28.482258,29.377827,30.273396,31.168964,32.064533,32.960106,33.855675,34.751244,35.646812,36.54238,37.43795,38.33352,39.229088,40.124657,41.020226,41.915794,42.811363,43.706932,44.602505,45.49807,46.393642,47.289207,48.18478,49.08035,49.975918,50.750286,50.595455,50.440628,50.314774,50.526936,50.7391,50.951263,51.163425,51.37559,51.587753,51.79992,52.01208,52.224243,52.43641,52.64857,52.860733,53.0729,53.28506,52.87157,52.37786,51.88415,51.39044,50.896732,50.403023,26.996666,26.28341,25.570154,24.856897,24.14364,23.430384,22.717129,22.00387,21.290613,20.577358,19.864101,20.75967,21.65524,22.550806,23.446375,24.341944,25.23751,26.13308,27.028648,27.924217,28.819786,29.715355,30.610922,31.50649,32.402058,33.297626,34.193195,35.088764,35.98433,36.8799,37.775467,38.671036,39.566605,40.462173,41.357742,42.25331,43.14888,44.04445,44.940018,45.835587,46.731155,47.626724,48.52229,49.41786,49.990242,49.835415,49.680584,49.6996,49.911762,50.123924,50.33609,50.548252,50.760418,50.97258,51.184742,51.396908,51.60907,51.821236,52.033398,52.24556,52.297306,51.803596,51.309883,50.816174,50.322464,49.828754,49.335045,27.810455,27.0972,26.383944,25.670687,24.95743,24.244175,23.530918,22.817661,22.104404,21.60068,22.589533,22.002245,21.414957,21.992758,22.888327,23.783895,24.679464,25.575035,26.470604,27.366173,28.261742,29.15731,30.05288,30.948448,31.844017,32.739586,33.635155,34.530724,35.426292,36.32186,37.21743,38.113,39.008568,39.904137,40.79971,41.695274,42.590843,43.486412,44.381985,45.277554,46.173122,47.068687,47.96426,48.85983,49.2302,49.075375,48.920547,49.08442,49.29658,49.508747,49.72091,49.933075,50.145237,50.357403,50.569565,50.78173,50.993893,51.20606,51.41822,51.229324,50.735615,50.241905,49.74819,49.254482,48.760773,48.267063,47.773354,29.337524,28.624268,27.911013,27.197756,26.484499,25.771244,25.057987,24.34473,23.631474,23.337206,25.902254,25.314962,24.72767,24.140379,23.553087,22.330303,23.225872,24.12144,25.01701,25.912579,26.808147,27.703716,28.599285,29.494854,30.390423,31.285992,32.18156,33.07713,33.9727,34.868267,35.763836,36.659405,37.554974,38.450542,39.34611,40.24168,41.13725,42.032818,42.928387,43.823956,44.719524,45.615093,46.510662,47.40623,48.624985,48.470158,48.31533,48.25708,48.469242,48.681408,48.89357,49.105736,49.317898,49.530064,49.742226,49.954388,50.166553,50.378716,50.655052,50.161343,49.667633,49.173923,48.680214,48.1865,47.69279,47.19908,46.70537,30.151318,29.43806,28.724802,28.011547,27.29829,26.585033,25.871778,25.158522,25.073784,26.874603,28.627686,28.040396,27.453104,26.865814,26.278524,25.691233,25.103943,24.516651,24.45896,25.354528,26.250097,27.145666,28.041235,28.936804,29.832373,30.727942,31.62351,32.51908,33.414646,34.310215,35.205784,36.101353,36.99692,37.89249,38.78806,39.683628,40.579197,41.474766,42.370335,43.265903,44.161472,45.05704,45.95261,46.84818,47.743748,47.71012,47.55529,47.641907,47.85407,48.066235,48.278397,48.490562,48.702724,48.914886,49.127052,49.339214,49.55138,49.587074,49.093365,48.599655,48.105946,47.612232,47.118523,46.624813,46.131104,45.637394,45.143684,31.678364,30.965107,30.25185,29.538595,28.825338,28.112082,27.398825,26.68557,26.81036,28.611174,30.411987,31.353117,30.765827,30.178537,29.591248,29.003958,28.416668,27.829378,27.242088,26.654797,26.067507,25.692049,26.587618,27.483187,28.378756,29.274326,30.169895,31.065464,31.961035,32.8566,33.752174,34.647743,35.543312,36.43888,37.33445,38.23002,39.125587,40.021156,40.91673,41.812298,42.707867,43.60344,44.49901,45.394577,46.290146,47.1049,46.950073,46.814568,47.02673,47.238895,47.451057,47.663223,47.875385,48.087547,48.299713,48.511875,49.012802,48.519093,48.025383,47.531673,47.037964,46.544254,46.050545,45.556835,45.063126,44.569416,44.075706,32.492176,31.77892,31.065662,30.352406,29.63915,28.925894,28.212639,28.546894,30.347733,32.14857,33.94941,34.07853,33.49124,32.903954,32.316666,31.729378,31.14209,30.554802,29.967514,29.380226,28.792938,28.20565,27.618362,27.031075,27.820705,28.716274,29.611843,30.507412,31.402983,32.298553,33.194122,34.08969,34.98526,35.88083,36.776398,37.671967,38.567535,39.463104,40.358673,41.254246,42.149815,43.045383,43.940956,44.836525,45.732094,46.344868,46.190037,46.199387,46.41155,46.623714,46.83588,47.048042,47.26021,47.47237,47.684536,47.896698,47.451115,46.957405,46.46369,45.969982,45.476273,44.982563,44.488853,43.995144,43.501434,43.007725,42.514015,34.019222,33.305965,32.59271,31.879452,31.166197,30.45294,29.739685,30.283472,32.084305,33.885136,35.685966,37.391254,36.803963,36.216675,35.629383,35.042095,34.454807,33.867516,33.280228,32.69294,32.105648,31.51836,30.93107,30.34378,29.756493,29.169203,28.158253,29.053822,29.94939,30.84496,31.740528,32.636097,33.531666,34.427235,35.322803,36.218372,37.11394,38.00951,38.90508,39.800648,40.696217,41.591785,42.487354,43.382923,44.278492,45.174057,45.58482,45.372047,45.584213,45.796375,46.00854,46.220703,46.432865,46.64503,46.857193,46.876842,46.383133,45.889423,45.395714,44.902004,44.408295,43.91458,43.42087,42.927162,42.433453,41.939743,41.446033,34.83302,34.119762,33.406506,32.69325,31.979992,31.266735,32.02005,33.820877,35.621704,37.42253,39.223354,40.116688,39.529396,38.94211,38.35482,37.76753,37.18024,36.59295,36.00566,35.418373,34.831085,34.243793,33.656506,33.069214,32.481926,31.894638,31.307348,30.720058,30.13277,30.28691,31.182478,32.078045,32.973614,33.869183,34.76475,35.66032,36.55589,37.451454,38.347023,39.24259,40.13816,41.03373,41.9293,42.824867,43.720436,44.616005,44.82478,44.756874,44.969036,45.181202,45.393364,45.60553,45.817696,46.029858,45.808865,45.315155,44.821445,44.327732,43.834023,43.340313,42.846603,42.352894,41.859184,41.36547,40.87176,40.695385,40.655003,36.36008,35.646828,34.93357,34.220314,33.507057,31.955746,33.756577,35.557407,37.358242,39.159073,40.959904,43.429405,42.842117,42.254826,41.667538,41.08025,40.49296,39.90567,39.318382,38.731094,38.143803,37.556515,36.969227,36.381935,35.794647,35.20736,34.62007,34.03278,33.44549,32.858204,32.270912,31.683624,31.519997,32.415565,33.31114,34.206707,35.102276,35.997845,36.893417,37.788986,38.684555,39.580124,40.475693,41.371265,42.266834,43.162403,44.219566,43.929535,44.1417,44.353863,44.566025,44.77819,44.990353,45.234592,44.740883,44.247173,43.753464,43.259754,42.766045,42.272335,41.778625,41.284916,40.609882,40.569496,40.529114,40.488728,40.44834,37.17387,36.460617,35.74736,35.034103,34.320847,35.493153,37.29398,39.094807,40.895634,42.69646,44.497288,46.154835,45.567547,44.980255,44.392967,43.805676,43.218388,42.6311,42.043808,41.45652,40.86923,40.28194,39.69465,39.10736,38.520073,37.93278,37.345493,36.7582,36.170914,35.583622,34.996334,34.409042,33.821754,33.234467,32.753113,33.64868,34.544247,35.439816,36.33538,37.23095,38.126514,39.022083,39.91765,40.813217,41.708782,42.60435,43.459526,43.314354,43.52652,43.73868,43.950848,44.163013,44.16661,43.6729,43.179195,42.685486,42.191776,41.698067,41.204357,40.710648,40.443604,40.403217,40.362835,40.32245,40.282066,40.24168,40.201298,38.700924,37.987667,37.27441,36.561153,35.42891,37.229733,39.030556,40.83138,42.632202,44.43303,46.233852,48.034676,48.88027,48.29298,47.70569,47.1184,46.531113,45.94382,45.356533,44.76924,44.181953,43.59466,43.007374,42.420086,41.832794,41.245506,40.65822,40.070927,39.483635,38.896347,38.30906,37.72177,37.13448,36.547188,35.9599,35.372612,34.78532,33.986202,34.88177,35.77734,36.67291,37.568478,38.464043,39.35961,40.25518,41.15075,42.046318,42.699486,42.69918,42.911343,43.123505,43.592354,43.098644,42.604935,42.111225,41.617516,41.123806,40.630096,40.31771,40.27733,40.236942,40.19656,40.156174,40.11579,40.075405,40.035023,39.994637,39.514732,38.80148,38.088223,37.374966,38.966263,40.76709,42.567917,44.368744,46.169575,47.9704,49.771233,51.57206,51.6057,51.018414,50.43112,49.843834,49.256546,48.669254,48.081966,47.494675,46.907387,46.3201,45.732807,45.14552,44.558228,43.97094,43.38365,42.79636,42.209072,41.62178,41.034492,40.447205,39.859913,39.272625,38.685333,38.098045,37.510757,36.923466,36.336178,35.748886,36.114857,37.010426,37.90599,38.80156,39.69713,40.592697,41.488262,41.939445,42.084003,42.296165,42.50833,42.03067,41.53696,41.04325,40.54954,40.191822,40.15144,40.111053,40.07067,40.030285,39.989902,39.949516,39.90913,39.868748,39.82836,39.78798,39.747593,41.041782,40.328526,39.61527,38.90201,40.70284,42.503662,44.30449,46.105312,47.906136,49.706963,51.50779,53.308613,54.918423,54.33113,53.743843,53.156555,52.569263,51.981976,51.394688,50.807396,50.220108,49.63282,49.04553,48.45824,47.87095,47.28366,46.696373,46.10908,45.521793,44.934505,44.347214,43.759926,43.172638,42.585346,41.99806,41.410767,40.82348,40.23619,39.6489,39.06161,38.47432,37.88703,37.299744,37.347946,38.24352,39.13909,40.03466,41.334232,41.256668,41.468826,41.456394,40.962685,40.46897,40.065933,40.025547,39.985165,39.94478,39.904392,39.86401,39.823624,39.78324,39.742855,39.702473,39.662086,39.621704,39.581318,39.540936,41.855568,41.142315,40.63859,42.43942,44.24025,46.041077,47.841904,49.642735,51.443565,53.244392,55.04522,56.84605,57.643837,57.05655,56.469257,55.88197,55.29468,54.70739,54.120102,53.532814,52.945522,52.358234,51.770947,51.183655,50.596367,50.00908,49.421787,48.8345,48.247208,47.65992,47.07263,46.485344,45.898052,45.310764,44.723473,44.136185,43.548897,42.961605,42.374317,41.787025,41.199738,40.61245,40.02516,39.437874,38.85058,38.58106,39.476616,40.372177,40.641483,40.388412,39.940037,39.899654,39.85927,39.818886,39.7785,39.738117,39.69773,39.65735,39.616962,39.57658,39.536194,39.49581,39.455425,39.415043,39.374657,39.334274,39.293888,43.38264,42.669384,42.37512,44.17595,45.97678,47.77761,49.578445,51.379276,53.180107,54.98094,56.78177,58.582603,60.956562,60.36927,59.781982,59.19469,58.607403,58.020115,57.432823,56.845535,56.258247,55.670956,55.083668,54.49638,53.90909,53.3218,52.734512,52.147224,51.559933,50.97264,50.385353,49.798065,49.210777,48.623486,48.036198,47.448906,46.861618,46.27433,45.687042,45.09975,44.512463,43.92517,43.337883,42.750595,42.163307,41.576015,40.988728,40.401436,39.814148,39.77376,39.73338,39.692993,39.65261,39.612225,39.571842,39.531456,39.491074,39.450687,39.410305,39.36992,39.329536,39.28915,39.248768,39.20838,39.168,39.127613,39.08723,44.196434,44.1117,45.91253,47.713356,49.514183,51.315014,53.115845,54.91667,56.717503,58.51833,60.31916,62.119987,63.68199,63.0947,62.507412,61.92012,61.332832,60.745544,60.158253,59.570965,58.983677,58.396385,57.809097,57.22181,56.634518,56.04723,55.459938,54.87265,54.285362,53.69807,53.110783,52.52349,51.936203,51.348915,50.761623,50.174335,49.587044,48.999756,48.412468,47.825176,47.23789,46.650597,46.06331,45.47602,44.888733,44.30144,43.71415,42.744576,40.84352,39.708054,39.622765,39.53748,39.452194,39.36691,39.3248,39.284412,39.24403,39.203644,39.163258,39.122875,39.08249,39.042107,39.00172,38.961338,38.92095,38.88057,38.840183,45.72348,45.848274,47.6491,49.44993,51.250755,53.051582,54.85241,56.653236,58.454063,60.25489,62.055717,63.856544,65.65737,66.407425,65.82014,65.23285,64.64555,64.058266,63.470978,62.88369,62.2964,61.70911,61.121822,60.53453,59.947243,59.359955,58.772663,58.185375,57.598087,57.010796,56.423508,55.83622,55.24893,54.66164,54.07435,53.48706,52.899773,52.312485,51.725197,51.137905,50.550617,49.963326,49.376038,48.78875,48.20146,47.61417,47.409187,45.675014,43.913586,41.87283,39.68724,39.601955,39.51667,39.431385,39.3461,39.26081,39.175526,39.09024,39.004955,38.916214,38.87583,38.835445,38.795063,38.754677,38.714294,38.67391,38.633526,47.5848,49.38563,51.18646,52.98729,54.78812,56.58895,58.38978,60.19061,61.99144,63.792267,65.593094,67.39393,69.194756,69.13286,68.54557,67.958275,67.37099,66.7837,66.19641,65.60912,65.021835,64.43454,63.84725,63.259964,62.672672,62.085384,61.498093,60.910805,60.323517,59.73623,59.148937,58.56165,57.974358,57.38707,56.799778,56.21249,55.6252,55.03791,54.450623,53.863335,53.276043,52.688755,52.101463,51.514175,50.926884,50.339596,48.605442,46.871292,44.942955,42.9022,40.861443,39.581142,39.495857,39.410572,39.325283,39.239998,39.154713,39.069427,38.984142,38.898857,38.813572,38.728287,38.643,38.557716,38.47243,38.426865,38.386482,49.32138,51.122208,52.923035,54.72386,56.52469,58.325516,60.126343,61.92717,63.728,65.528824,67.32965,69.13048,70.931305,72.44557,71.858284,71.270996,70.6837,70.09641,69.509125,68.92184,68.33455,67.74725,67.159966,66.57268,65.98539,65.3981,64.81081,64.22352,63.63623,63.04894,62.46165,61.87436,61.28707,60.699783,60.11249,59.525204,58.937912,58.350624,57.763336,57.176044,56.588753,56.001465,55.414177,54.82689,54.239597,53.27001,51.535873,49.80173,48.01309,45.972332,43.931572,41.890816,39.56033,39.475044,39.38976,39.304474,39.21919,39.133904,39.04862,38.963333,38.878048,38.79276,38.707474,38.62219,38.536903,38.45162,38.366333,52.858788,54.65961,56.460438,58.26126,60.062088,61.86291,63.663734,65.46456,67.26539,69.06621,70.867035,72.66786,74.46869,75.171,74.58371,73.99642,73.409134,72.821846,72.23455,71.64726,71.059975,70.47269,69.8854,69.29811,68.71082,68.12353,67.53624,66.94895,66.361664,65.774376,65.18709,64.5998,64.01251,63.425217,62.83793,62.25064,61.663353,61.076065,60.488773,59.901485,59.314194,58.726906,58.139618,57.55233,56.20047,54.46631,52.732147,50.99799,49.042397,47.00164,44.960884,42.920128,40.87937,39.454235,39.368946,39.28366,39.198376,39.11309,39.027805,38.94252,38.857235,38.77195,38.686665,38.60138,38.51609,38.430805,38.34552,54.595314,56.39614,58.196968,59.997795,61.798622,63.59945,65.400276,67.2011,69.00193,70.802765,72.60359,74.40441,76.20524,78.48372,77.89643,77.30914,76.721855,76.13457,75.54727,74.959984,74.372696,73.78541,73.19812,72.61083,72.02354,71.43625,70.84896,70.26167,69.674385,69.0871,68.4998,67.91251,67.325226,66.73794,66.15065,65.563354,64.97607,64.38878,63.80149,63.2142,62.62691,62.03962,61.45233,60.865044,59.130894,57.39674,55.66259,53.928436,52.112526,50.07177,48.031013,45.990257,43.9495,41.908745,39.433422,39.348137,39.26285,39.177567,39.09228,39.006996,38.92171,38.836426,38.75114,38.66585,38.580566,38.49528,38.409996,58.132725,59.933556,61.734383,63.535213,65.336044,67.13687,68.9377,70.73853,72.53936,74.340195,76.14102,77.94185,79.742676,81.20914,80.62185,80.03456,79.44727,78.85998,78.27269,77.6854,77.098114,76.510826,75.92354,75.33624,74.748955,74.16167,73.57438,72.98709,72.399796,71.81251,71.22522,70.63793,70.050644,69.463356,68.87607,68.28877,67.701485,67.1142,66.52691,65.93962,65.352325,64.76504,63.795456,62.06131,60.327164,58.59302,56.858875,55.124733,53.141888,51.101124,49.06036,47.019592,44.97883,42.938065,40.8973,39.32732,39.242035,39.15675,39.071465,38.98618,38.900894,38.81561,38.730324,38.64504,38.559753,38.47447,38.389183,59.8693,61.670128,63.47096,65.27179,67.07262,68.87344,70.67427,72.4751,74.275925,76.07675,77.87758,79.678406,81.47924,83.28007,83.93457,83.34728,82.759995,82.17271,81.58542,80.99812,80.410835,79.82355,79.23626,78.64897,78.06168,77.474396,76.88711,76.29982,75.712524,75.12524,74.53795,73.95066,73.36337,72.776085,72.1888,71.6015,71.01421,70.426926,69.83964,69.25235,68.66506,68.460075,66.725914,64.99176,63.257607,61.52345,59.78929,58.055138,56.211964,54.171207,52.13045,50.08969,48.048935,46.00818,43.967422,41.926666,39.30651,39.221226,39.13594,39.050655,38.96537,38.880085,38.7948,38.709515,38.62423,38.538944,38.45366,63.406662,65.2075,67.00832,68.80915,70.609985,72.41081,74.21164,76.01247,77.8133,79.614136,81.41496,83.21579,85.01662,86.81745,86.66,86.072716,85.48543,84.89814,84.31085,83.72356,83.13627,82.54898,81.96169,81.374405,80.78712,80.19982,79.61253,79.025246,78.43796,77.85067,77.26338,76.67609,76.0888,75.50151,74.91422,74.326935,73.73965,73.15236,72.56506,71.977776,71.39049,69.656334,67.92219,66.188034,64.45388,62.71973,60.98558,59.251427,57.241333,55.200577,53.15982,51.119064,49.07831,47.03755,44.996796,42.95604,40.915283,39.200417,39.11513,39.029846,38.94456,38.859276,38.77399,38.688705,38.60342,38.51813,38.432846,65.143234,66.94406,68.744896,70.54572,72.34655,74.14738,75.948204,77.74904,79.549866,81.35069,83.15152,84.95235,86.753174,88.55401,89.972725,89.38544,88.79815,88.21086,87.62357,87.03628,86.44899,85.8617,85.274414,84.687126,84.09983,83.51254,82.925255,82.33797,81.75067,81.16338,80.576096,79.98881,79.40152,78.81423,78.22694,77.63965,77.05236,76.46507,75.877785,75.29049,74.3209,72.58675,70.85259,69.11844,67.384285,65.65013,63.915977,62.181824,60.311398,58.27064,56.229885,54.18913,52.148373,50.107616,48.06686,46.026104,43.985348,41.94459,39.179604,39.09432,39.009033,38.923748,38.838463,38.753178,38.667892,38.582607,38.497322,68.68063,70.48146,72.28229,74.08312,75.88394,77.68478,79.4856,81.28643,83.08726,84.888084,86.68891,88.48974,90.290565,92.09139,92.69816,92.11087,91.52358,90.936295,90.34901,89.76172,89.17443,88.587135,87.99985,87.41256,86.82527,86.23798,85.650696,85.0634,84.47611,83.888824,83.30154,82.71425,82.12696,81.53967,80.95238,80.36509,79.7778,79.19051,78.603226,77.251366,75.51721,73.78306,72.048904,70.31474,68.58059,66.846436,65.112274,63.37812,61.34077,59.300014,57.25926,55.218502,53.177746,51.13699,49.096233,47.055473,45.01472,42.973965,40.933205,39.07351,38.988224,38.90294,38.817654,38.73237,38.647083,38.561794,38.47651,70.417175,72.218,74.01883,75.81966,77.62048,79.42132,81.222145,83.02297,84.82381,86.62463,88.42546,90.22629,92.027115,93.82794,96.01089,95.42359,94.8363,94.249016,93.66173,93.07444,92.487144,91.89986,91.31257,90.72528,90.13799,89.550705,88.96341,88.37612,87.78883,87.201546,86.61426,86.02696,85.439674,84.85239,84.2651,83.67781,83.090515,82.50323,81.91594,80.181786,78.44764,76.713486,74.97933,73.24518,71.51103,69.77688,68.042725,66.45166,64.410904,62.370148,60.329388,58.28863,56.247875,54.20712,52.166363,50.125603,48.084846,46.04409,44.003334,41.962578,39.052696,38.96741,38.882126,38.79684,38.71155,38.626266,38.54098,73.95457,75.755394,77.55622,79.35705,81.157875,82.9587,84.75953,86.560356,88.36118,90.16201,91.96284,93.763664,95.56449,97.36532,98.736305,98.14902,97.56172,96.974434,96.387146,95.79986,95.21257,94.62528,94.03799,93.4507,92.86341,92.27612,91.688835,91.10155,90.51425,89.92696,89.339676,88.75239,88.1651,87.57781,86.990524,86.40323,85.81594,84.84635,83.1122,81.378044,79.64389,77.909744,76.17558,74.44144,72.707275,70.97313,69.23897,67.480965,65.44021,63.399456,61.3587,59.31794,57.277184,55.236427,53.19567,51.154915,49.11416,47.073402,45.032646,42.99189,40.95113,38.946598,38.861313,38.776028,38.690742,38.605457,38.52017,75.69115,77.491974,79.2928,81.09363,82.894455,84.69528,86.49611,88.296936,90.09776,91.89859,93.69942,95.50024,97.30107,99.1019,102.04904,101.461754,100.87446,100.28717,99.69988,99.112595,98.52531,97.93801,97.35072,96.763435,96.17615,95.58885,95.001564,94.414276,93.82699,93.2397,92.652405,92.06512,91.47783,90.89053,90.303246,89.71596,89.51097,87.77682,86.042656,84.3085,82.57435,80.840195,79.10604,77.37189,75.63773,73.90358,72.16942,70.551094,68.51034,66.46958,64.428825,62.38807,60.347313,58.306557,56.2658,54.225044,52.184288,50.143528,48.102776,46.062016,44.02126,41.980503,39.939747,38.840504,38.75522,38.66993,38.584644,79.22851,81.029335,82.83016,84.63099,86.431816,88.23264,90.03347,91.8343,93.635124,95.43595,97.23678,99.037605,100.83843,102.63927,104.440094,104.18717,103.59988,103.01259,102.4253,101.83801,101.250725,100.66343,100.07614,99.48885,98.901566,98.31427,97.72698,97.139694,96.55241,95.96511,95.37782,94.790535,94.20325,93.61595,93.02866,92.441376,90.70722,88.973076,87.23892,85.50477,83.77062,82.03647,80.30232,78.56817,76.834015,75.09987,73.365715,71.58047,69.5397,67.49895,65.45818,63.417423,61.376663,59.335903,57.295143,55.254383,53.213623,51.17286,49.132103,47.091343,45.050583,43.00982,40.969063,38.9283,38.734406,38.64912,38.563835,80.965096,82.76592,84.56676,86.367584,88.16841,89.96924,91.770065,93.5709,95.37173,97.172554,98.97338,100.774216,102.57504,104.37587,106.1767,107.49988,106.91258,106.325294,105.73801,105.15072,104.56343,103.97614,103.38885,102.80156,102.21427,101.62698,101.039696,100.45241,99.86511,99.277824,98.69054,98.10325,97.51596,96.928665,96.34138,95.37179,93.63764,91.90349,90.169334,88.43518,86.701035,84.96688,83.23273,81.49857,79.76442,78.03027,76.29612,74.650536,72.60978,70.56902,68.52827,66.48751,64.446754,62.405994,60.36524,58.324482,56.283722,54.24297,52.20221,50.161453,48.120697,46.07994,44.039185,41.99843,39.95767,38.713593,38.628304,84.502495,86.30332,88.10415,89.904976,91.70581,93.50664,95.307465,97.10829,98.90912,100.709946,102.51077,104.3116,106.11243,107.91325,109.71408,110.22531,109.63802,109.050735,108.46344,107.87615,107.288864,106.70158,106.11429,105.527,104.93971,104.352425,103.76514,103.17784,102.59055,102.003265,101.41598,100.82869,100.2414,99.65411,98.30226,96.56811,94.833954,93.0998,91.36565,89.63149,87.89734,86.163185,84.42903,82.69488,80.960724,79.22657,77.49242,75.67991,73.639145,71.59839,69.55763,67.51688,65.47611,63.435356,61.3946,59.35384,57.31308,55.272324,53.231564,51.190804,49.150047,47.10929,45.06853,43.02777,40.98701,38.946255,38.607494,86.23904,88.03986,89.84069,91.641525,93.44235,95.24318,97.04401,98.84483,100.64567,102.446495,104.24733,106.04816,107.84898,109.64981,111.45064,113.53803,112.950745,112.36346,111.77616,111.18887,110.601585,110.0143,109.42701,108.83972,108.252426,107.66514,107.07785,106.49056,105.903275,105.31599,104.7287,104.1414,103.554115,102.96683,101.23267,99.49853,97.76437,96.03022,94.296074,92.56192,90.82777,89.09362,87.35947,85.62531,83.89116,82.15701,80.42286,78.75004,76.709274,74.66852,72.62776,70.587,68.54624,66.505486,64.46473,62.42397,60.38321,58.342453,56.301693,54.260933,52.220177,50.17942,48.138664,46.097904,44.057144,42.016388,39.975628,89.77643,91.577255,93.37808,95.17892,96.979744,98.78057,100.5814,102.382225,104.18306,105.98389,107.78471,109.58554,111.38637,113.187195,114.98802,116.263466,115.67618,115.08888,114.501595,113.91431,113.32702,112.73973,112.152435,111.56515,110.97786,110.39057,109.80328,109.21599,108.6287,108.04141,107.454124,106.86683,105.89724,104.16309,102.42894,100.694786,98.96063,97.22648,95.492325,93.75817,92.02402,90.28987,88.55572,86.82156,85.08741,83.35326,81.6191,79.77934,77.73859,75.69783,73.657074,71.61632,69.57556,67.534805,65.49405,63.45329,61.412533,59.371777,57.33102,55.290264,53.249508,51.20875,49.167995,47.12724,45.086483,43.045723,41.004967,91.513,93.31383,95.114655,96.91548,98.71631,100.517136,102.31796,104.11879,105.91962,107.72044,109.52127,111.3221,113.122925,114.92375,116.72458,119.57619,118.9889,118.40161,117.81432,117.227036,116.63974,116.05245,115.465164,114.87788,114.29059,113.7033,113.11601,112.52872,111.94143,111.35414,110.76685,110.56187,108.82771,107.09356,105.359406,103.625244,101.8911,100.15694,98.42278,96.68863,94.954475,93.22032,91.48617,89.752014,88.01786,86.28371,84.54955,82.84947,80.80871,78.76795,76.727196,74.68644,72.645676,70.60492,68.56416,66.52341,64.48265,62.44189,60.40113,58.360374,56.31962,54.278862,52.238102,50.197342,48.156586,46.11583,44.07507,95.05036,96.85119,98.652016,100.45284,102.25368,104.054504,105.85533,107.65616,109.456985,111.25781,113.05864,114.85947,116.66029,118.46112,120.26195,122.06278,121.71432,121.12703,120.53974,119.95245,119.365166,118.77788,118.19059,117.6033,117.01601,116.42872,115.84143,115.25414,114.666855,114.07957,113.49228,111.758125,110.02398,108.289825,106.55567,104.821526,103.08737,101.35322,99.619064,97.88492,96.150764,94.41661,92.682465,90.94831,89.21416,87.48001,85.74586,83.878845,81.83809,79.797325,77.75657,75.715805,73.67505,71.63429,69.59353,67.55277,65.51201,63.471252,61.43049,59.389732,57.348972,55.308212,53.267452,51.226692,49.185932,47.145172,45.104416,96.78693,98.58775,100.38858,102.18941,103.990234,105.79106,107.591896,109.392715,111.19354,112.99437,114.795204,116.59602,118.39685,120.19768,121.99851,123.79934,125.02704,124.43975,123.85246,123.265175,122.67788,122.09059,121.5033,120.916016,120.32872,119.74143,119.154144,118.56686,117.97957,117.39227,116.42268,114.68854,112.954384,111.22023,109.48608,107.75192,106.01777,104.283615,102.54947,100.815315,99.08116,97.34701,95.612854,93.8787,92.14455,90.4104,88.67624,86.948906,84.90815,82.86739,80.82664,78.78588,76.745125,74.70436,72.663605,70.62285,68.58209,66.541336,64.50058,62.459827,60.41907,58.378315,56.33756,54.296803,52.256042,50.21529,48.17453,100.32433,102.12516,103.92598,105.72681,107.52763,109.32846,111.12929,112.930115,114.73094,116.53177,118.332596,120.13342,121.93425,123.73507,125.5359,127.33672,127.75247,127.165184,126.577896,125.99061,125.40332,124.81603,124.228745,123.64145,123.05416,122.46687,121.879585,121.2923,120.70501,119.35316,117.619,115.88485,114.150696,112.41654,110.68239,108.948235,107.21408,105.47993,103.74577,102.01162,100.277466,98.54332,96.80916,95.07501,93.34085,91.606705,89.87254,87.97828,85.93752,83.89677,81.85601,79.81525,77.77449,75.733734,73.69298,71.65222,69.61146,67.5707,65.529945,63.48919,61.44843,59.40767,57.366913,55.326157,53.285397,51.24464,49.20388,102.06089,103.861725,105.66255,107.46338,109.264206,111.06504,112.86587,114.666695,116.46753,118.26836,120.06918,121.87001,123.670845,125.47167,127.27251,129.07333,131.06519,130.47789,129.89061,129.30331,128.71603,128.12874,127.54145,126.95416,126.366875,125.77959,125.1923,124.60501,124.01772,122.28357,120.549416,118.81526,117.08111,115.346954,113.6128,111.87865,110.14449,108.41034,106.676186,104.94203,103.20788,101.473724,99.73956,98.00542,96.271255,94.53711,92.802956,91.048355,89.0076,86.96684,84.92609,82.88533,80.84457,78.80381,76.763054,74.7223,72.68154,70.640785,68.60003,66.55927,64.51852,62.47776,60.437,58.396244,56.355488,54.31473,52.273975,105.59829,107.399124,109.19995,111.00078,112.801605,114.60243,116.40326,118.20409,120.00492,121.80574,123.606575,125.4074,127.20824,129.00906,130.80989,132.61072,133.79062,133.20332,132.61604,132.02875,131.44145,130.85417,130.26688,129.6796,129.0923,128.50502,127.917725,126.948135,125.21399,123.479836,121.74568,120.01153,118.277374,116.54323,114.809074,113.07492,111.34077,109.60661,107.87247,106.13831,104.40416,102.670006,100.93585,99.201706,97.467545,95.7334,93.99925,92.07772,90.036964,87.99621,85.95545,83.914696,81.87394,79.83318,77.79243,75.75167,73.710915,71.67015,69.629395,67.58864,65.54788,63.507126,61.46637,59.425613,57.384857,55.3441,53.303345]
+ examples/rasterize/rasterize.hs view
@@ -0,0 +1,111 @@+{-+ Copyright (C) 2010 by IPwn Studios+ Released under GNU General Public License v3+-}+import qualified RasterizeAcc++import Control.Applicative+import Control.Arrow+import Data.Array (Array)+import Data.Array.IArray as A+import qualified Data.Array.Accelerate as Acc+import qualified Data.Array.Accelerate.Interpreter as Acc+import Data.List+import Data.Ord+import Debug.Trace+import System.IO++main :: IO ()+main = do+ test rasterizeH "rasterize-test1.txt"+ test rasterizeH "rasterize-test2.txt"+ test rasterizeH "rasterize-test3.txt"+ test rasterizeH "rasterize-test4.txt"+ test rasterizeAI "rasterize-test1.txt"+ test rasterizeAI "rasterize-test2.txt"+ test rasterizeAI "rasterize-test3.txt"+ test rasterizeAI "rasterize-test4.txt"+ where+ rasterizeH = (rasterize, "Haskell")+ rasterizeAI = (rasterizeAI_, "Accelerate interpreted")+ rasterizeAI_ :: Area -> [Value] -> [Facet] -> [Float]+ rasterizeAI_ area@((x0,y0),(x1,y1)) values facets =+ let acc = RasterizeAcc.rasterize + (Acc.tuple (Acc.tuple (Acc.constant x0, Acc.constant y0),+ Acc.tuple (Acc.constant x1, Acc.constant y1)))+ (Acc.use $ Acc.fromList (length values) values)+ (Acc.use $ Acc.fromList (length facets) facets)+ out = Acc.toList $ Acc.run acc+ in out + where+ v2acc ((x, y), v) = Acc.tuple (Acc.tuple (Acc.constant x, Acc.constant y), Acc.constant v)+ f2acc (a, b, c) = Acc.tuple (Acc.constant a, Acc.constant b, Acc.constant c)++test :: (Area -> [Insertion] -> [Facet] -> [Float], String) -> FilePath -> IO ()+test (rast, descr) fn = do+ (values, facets, area, sb) <- withFile fn ReadMode $ \h -> do+ values <- read <$> hGetLine h + facets <- read <$> hGetLine h+ area <- read <$> hGetLine h+ sb <- read <$> hGetLine h+ return (values, facets, area, sb)+ let is = rast area values facets+ if sb `similarTo` is+ then putStrLn $ fn ++ " (" ++ descr ++ ") - pass"+ else putStrLn $ fn ++ " (" ++ descr ++ ") - fail - "+++ show (length sb)++" vs. "++show (length is)++" got "++show (zip is sb) ++similarTo :: [Float] -> [Float] -> Bool+similarTo xs ys = and (zipWith near xs ys) && length xs == length ys+ where+ near x y = abs (x - y) < 0.001++type Area = ((Int, Int), (Int, Int))+type Value = ((Int, Int), Float)+type Insertion = ((Int, Int), Float)+type Facet = (Int, Int, Int)++-- | Rasterize the specified facets, clipping to area.+-- Any gaps are filled with 0 values.+rasterize :: Area -> [Value] -> [Facet] -> [Float]+rasterize area@((x0,y0),(x1,y1)) values facets = toArray $ concatMap tri facets+ where+ tri :: (Int,Int,Int) -> [((Int, Int), Float)]+ tri (iA,iB,iC) =+ -- Sort by increasing X+ let [(aInt@(axInt, _), vA),+ (bInt, vB),+ (cInt@(cxInt, _), vC)] = sortBy (comparing xCoord) $+ map (values !!) [iA,iB,iC]+ -- Scan across+ a@(ax, _) = fromIntegral *** fromIntegral $ aInt :: (Float, Float)+ b@(bx, _) = fromIntegral *** fromIntegral $ bInt :: (Float, Float)+ c@(cx, _) = fromIntegral *** fromIntegral $ cInt :: (Float, Float)+ in flip concatMap [(max x0 axInt)..(min x1 (cxInt-1))] $ \xInt ->+ let x = fromIntegral xInt :: Float+ (yAC, vAC) = (interpolate a c x, interpolate (ax,vA) (cx,vC) x)+ (yOther, vOther) = if x < bx+ then (interpolate a b x, interpolate (ax,vA) (bx,vB) x)+ else (interpolate b c x, interpolate (bx,vB) (cx,vC) x)+ -- Order AC and Other so that y is increasing+ (yBot, vBot, yTop, vTop) = if yAC <= yOther+ then (yAC, vAC, yOther, vOther)+ else (yOther, vOther, yAC, vAC)+ yStart = max y0 (round yBot)+ yEnd = min y1 (round yTop - 1)+ -- Displace odd columns because the terrain mesh is hexagonal+ hexify y | even xInt = fromIntegral y+ hexify y = fromIntegral y + 0.5+ in flip map [yStart .. yEnd] $ \yInt ->+ ((xInt, yInt), interpolate (yBot, vBot) (yTop, vTop) (hexify yInt))+ where+ xCoord ((x, _), _) = x++ interpolate :: (Float, Float) -> (Float, Float) -> Float -> Float+ interpolate (t0, x0) (t1, x1) t = (t - t0) * (x1 - x0) / (t1 - t0) + x0++ toArray :: [Insertion] -> [Float]+ toArray output =+ let output' = A.accumArray (flip const) 0 area output :: Array (Int, Int) Float+ in A.elems output'+
examples/simple/Filter.hs view
@@ -2,7 +2,7 @@ module Filter (filter, filter_ref) where -import Prelude hiding (replicate, zip, map, filter, max, min, not, zipWith)+import Prelude hiding (replicate, scanl, zip, map, filter, max, min, not, zipWith) import qualified Prelude import Data.Array.Unboxed (UArray)@@ -11,13 +11,14 @@ import Data.Array.Accelerate + filter :: Elem a => (Exp a -> Exp Bool) -> Acc (Vector a) -> Acc (Vector a) filter p arr = let flags = map (boolToInt . p) arr- (targetIdx, length) = scan (+) 0 flags+ (targetIdx, length) = scanl (+) 0 flags arr' = backpermute (length!(constant ())) id arr in permute const arr' (\ix -> flags!ix ==* 0 ? (ignore, targetIdx!ix)) arr@@ -27,6 +28,7 @@ -- Instead, we should have a primitive that directly encodes the -- compaction pattern of the permutation function. + filter_ref :: IArray UArray e => (e -> Bool) -> UArray Int e
examples/simple/Main.hs view
@@ -11,11 +11,14 @@ import qualified Data.Array.Accelerate as Acc import qualified Data.Array.Accelerate.Interpreter as Interp+import qualified Data.Array.Accelerate.CUDA as CUDA import Time import SAXPY+import Square import DotP import Filter+import Sum -- Auxilliary array functions@@ -79,10 +82,15 @@ validateFloats :: Ix ix => UArray ix Float -> UArray ix Float -> IO () validateFloats arr_ref arr | arr_ref `similar` arr = putStrLn "Valid."- | otherwise = putStrLn "INVALID!"+ | otherwise = putStrLn "INVALID!" >> diff arr_ref arr where- similar arr1 arr2 = all (< epsilon) [abs ((x - y) / x) | x <- elems arr1 - | y <- elems arr2]+ similar arr1 arr2 = all (< epsilon) [abs ((x - y) / (x + y + epsilon)) + | x <- elems arr1 + | y <- elems arr2]+ diff arr1 arr2 = sequence_ [if abs ((x - y) / x) < epsilon+ then return ()+ else putStrLn $ ">>> " ++ "(" ++ show x ++ ", " ++ show y ++ ")"+ | x <- elems arr1 | y <- elems arr2] epsilon = 0.0001 @@ -126,6 +134,25 @@ end <- getTime return (r, end `minus` start) +timeScalar' :: (IArray UArray e, Acc.Elem e)+ => (() -> IO (Acc.Scalar e)) -> IO (UArray () e)+{-# NOINLINE timeScalar' #-}+timeScalar' testee + = do+ (r, time1) <- oneRun testee+ (r, time2) <- oneRun testee+ (r, time3) <- oneRun testee+ putStrLn $ showMinAvgMax milliseconds [time1, time2, time3] +++ " (wall - cpu min/avg/max in ms)"+ return $ Acc.toIArray r+ where+ oneRun testee = do+ start <- getTime+ r <- testee ()+ evaluateScalar r+ end <- getTime+ return (r, end `minus` start)+ timeUVector :: IArray UArray e => (() -> UArray Int e) -> IO (UArray Int e) {-# NOINLINE timeUVector #-} timeUVector testee @@ -165,6 +192,25 @@ return (r, end `minus` start) +timeVector' :: (IArray UArray e, Acc.Elem e)+ => (() -> IO (Acc.Vector e)) -> IO (UArray Int e)+{-# NOINLINE timeVector' #-}+timeVector' testee + = do+ (r, time1) <- oneRun testee+ (r, time2) <- oneRun testee+ (r, time3) <- oneRun testee+ putStrLn $ showMinAvgMax milliseconds [time1, time2, time3] +++ " (wall - cpu min/avg/max in ms)"+ return $ Acc.toIArray r+ where+ oneRun testee = do+ start <- getTime+ r <- testee ()+ evaluateVector r+ end <- getTime+ return (r, end `minus` start)+ -- Tests -- ----- @@ -179,10 +225,16 @@ v2 <- convertUVector v2_ref putStrLn "Running reference code..." ref_result <- timeUVector $ saxpy_ref' 1.5 v1_ref v2_ref+ putStrLn "[Interpreter]" putStrLn "Running Accelerate code..." result <- timeVector $ saxpy_interp 1.5 v1 v2 putStrLn "Validating result..." validateFloats ref_result result+ putStrLn "[CUDA]"+ putStrLn "Running Accelerate code..."+ result_cuda <- timeVector' $ saxpy_cuda 1.5 v1 v2+ putStrLn "Validating result..."+ validateFloats ref_result result_cuda where -- idiom with NOINLINE and extra parameter needed to prevent optimisations -- from sharing results over multiple runs@@ -190,7 +242,67 @@ saxpy_ref' a arr1 arr2 () = saxpy_ref a arr1 arr2 {-# NOINLINE saxpy_interp #-} saxpy_interp a arr1 arr2 () = Interp.run (saxpy a arr1 arr2)+ {-# NOINLINE saxpy_cuda #-}+ saxpy_cuda a arr1 arr2 () = CUDA.run (saxpy a arr1 arr2) +test_square :: Int -> IO ()+test_square n+ = do+ putStrLn "== Square"+ putStrLn $ "Generating data (n = " ++ show n ++ ")..."+ v1_ref <- randomUVector n+ v1 <- convertUVector v1_ref+ putStrLn "Running reference code..."+ ref_result <- timeUVector $ square_ref' v1_ref+ putStrLn "[Interpreter]"+ putStrLn "Running Accelerate code..."+ result <- timeVector $ square_interp v1+ putStrLn "Validating result..."+ validateFloats ref_result result+ putStrLn "[CUDA]"+ putStrLn "Running Accelerate code..."+ result_cuda <- timeVector' $ square_cuda v1+ putStrLn "Validating result..."+ validateFloats ref_result result_cuda+ where+ -- idiom with NOINLINE and extra parameter needed to prevent optimisations+ -- from sharing results over multiple runs+ {-# NOINLINE square_ref' #-}+ square_ref' arr1 () = square_ref arr1+ {-# NOINLINE square_interp #-}+ square_interp arr1 () = Interp.run (square arr1)+ {-# NOINLINE square_cuda #-}+ square_cuda arr1 () = CUDA.run (square arr1)++test_sum :: Int -> IO ()+test_sum n+ = do+ putStrLn "== Sum"+ putStrLn $ "Generating data (n = " ++ show n ++ ")..."+ v1_ref <- randomUVector n+ v1 <- convertUVector v1_ref+ putStrLn "Running reference code..."+ ref_result <- timeUScalar $ sum_ref' v1_ref+ putStrLn "[Interpreter]"+ putStrLn "Running Accelerate code..."+ result <- timeScalar $ sum_interp v1+ putStrLn "Validating result..."+ validateFloats ref_result result+ putStrLn "[CUDA]"+ putStrLn "Running Accelerate code..."+ result_cuda <- timeScalar' $ sum_cuda v1+ putStrLn "Validating result..."+ validateFloats ref_result result_cuda+ where+ -- idiom with NOINLINE and extra parameter needed to prevent optimisations+ -- from sharing results over multiple runs+ {-# NOINLINE sum_ref' #-}+ sum_ref' arr1 () = sum_ref arr1+ {-# NOINLINE sum_interp #-}+ sum_interp arr1 () = Interp.run (Sum.sum arr1)+ {-# NOINLINE sum_cuda #-}+ sum_cuda arr1 () = CUDA.run (Sum.sum arr1)+ test_dotp :: Int -> IO () test_dotp n = do@@ -203,9 +315,14 @@ putStrLn "Running reference code..." ref_result <- timeUScalar $ dotp_ref' v1_ref v2_ref putStrLn "Running Accelerate code..."+ putStrLn "[Interpreter]" result <- timeScalar $ dotp_interp v1 v2 putStrLn "Validating result..." validateFloats ref_result result+ putStrLn "[CUDA]"+ result_cuda <- timeScalar' $ dotp_cuda v1 v2+ putStrLn "Validating result..."+ validateFloats ref_result result_cuda where -- idiom with NOINLINE and extra parameter needed to prevent optimisations -- from sharing results over multiple runs@@ -213,6 +330,8 @@ dotp_ref' arr1 arr2 () = dotp_ref arr1 arr2 {-# NOINLINE dotp_interp #-} dotp_interp arr1 arr2 () = Interp.run (dotp arr1 arr2)+ {-# NOINLINE dotp_cuda #-}+ dotp_cuda arr1 arr2 () = CUDA.run (dotp arr1 arr2) test_filter :: Int -> IO () test_filter n@@ -224,9 +343,14 @@ putStrLn "Running reference code..." ref_result <- timeUVector $ filter_ref' (< 0) v_ref putStrLn "Running Accelerate code..."+ putStrLn "[Interpreter]" result <- timeVector $ filter_interp (Acc.<* Acc.constant 0) (Acc.use v) putStrLn "Validating result..." validateFloats ref_result result+ putStrLn "[CUDA]"+ result_cuda <- timeVector' $ filter_cuda (Acc.<* Acc.constant 0) (Acc.use v)+ putStrLn "Validating result..."+ validateFloats ref_result result_cuda where -- idiom with NOINLINE and extra parameter needed to prevent optimisations -- from sharing results over multiple runs@@ -234,6 +358,8 @@ filter_ref' p arr () = filter_ref p arr {-# NOINLINE filter_interp #-} filter_interp p arr () = Interp.run (filter p arr)+ {-# NOINLINE filter_cuda #-}+ filter_cuda p arr () = CUDA.run (filter p arr) main :: IO () main@@ -243,4 +369,4 @@ test_saxpy 100000 test_dotp 100000- test_filter 2000+ test_filter 1800
examples/simple/Makefile view
@@ -2,12 +2,15 @@ all: ghc $(HCFLAGS) -c Time.hs+ ghc $(HCFLAGS) -c Square.hs+ ghc $(HCFLAGS) -c Sum.hs ghc $(HCFLAGS) -c SAXPY.hs ghc $(HCFLAGS) -c SMVM.hs ghc $(HCFLAGS) -c DotP.hs ghc $(HCFLAGS) -c Filter.hs ghc $(HCFLAGS) -c Main.hs- ghc $(HCFLAGS) -o test Main.o Time.o SAXPY.o SMVM.o DotP.o Filter.o+ ghc $(HCFLAGS) -o test Main.o Time.o Square.o Sum.o SAXPY.o SMVM.o DotP.o \+ Filter.o clean: rm -f *.o *.hi test
examples/simple/SAXPY.hs view
@@ -16,9 +16,9 @@ xs' = use xs ys' = use ys in - zipWith (\x y -> constant alpha * x * y) xs' ys'+ zipWith (\x y -> constant alpha * x + y) xs' ys' saxpy_ref :: Float -> UArray Int Float -> UArray Int Float -> UArray Int Float saxpy_ref alpha xs ys- = listArray (bounds xs) [alpha * x * y | x <- elems xs | y <- elems ys]+ = listArray (bounds xs) [alpha * x + y | x <- elems xs | y <- elems ys]
+ examples/simple/Square.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE ParallelListComp #-}++module Square (square, square_ref) where++import Prelude hiding (replicate, zip, map, filter, max, min, not, zipWith)+import qualified Prelude++import Data.Array.Unboxed+import Data.Array.IArray++import Data.Array.Accelerate++square :: Vector Float -> Acc (Vector Float)+square xs+ = let+ xs' = use xs+ in + map (\x -> x * x) xs'++square_ref :: UArray Int Float -> UArray Int Float+square_ref xs+ = listArray (bounds xs) [x * x| x <- elems xs]+
+ examples/simple/Sum.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE ParallelListComp #-}++module Sum (sum, sum_ref) where++import Prelude hiding (replicate, zip, map, filter, max, min, not, zipWith, sum)+import qualified Prelude++import Data.Array.Unboxed+import Data.Array.IArray++import Data.Array.Accelerate++sum :: Vector Float -> Acc (Scalar Float)+sum xs+ = let+ xs' = use xs+ in + fold (\x y -> x + y) (constant 0.0) xs'++sum_ref :: UArray Int Float -> UArray () Float+sum_ref xs+ = listArray ((), ()) $ [Prelude.sum $ elems xs]+