/Data/Array/Accelerate/CUDA/Analysis/Hash.hs
https://github.com/sajith/accelerate · Haskell · 143 lines · 79 code · 18 blank · 46 comment · 1 complexity · ce56c0f94da7beff4fad98f8c0d59841 MD5 · raw file
- {-# LANGUAGE CPP, GADTs #-}
- -- |
- -- Module : Data.Array.Accelerate.CUDA.Analysis.Hash
- -- Copyright : [2008..2011] 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 (
- AccKey, accToKey, hashAccKey
- ) where
- import Data.Char
- import Language.C
- import Text.PrettyPrint
- import Codec.Compression.Zlib
- import Data.ByteString.Lazy.Char8 (ByteString)
- import qualified Data.ByteString.Lazy.Char8 as L
- import qualified Data.HashTable as Hash
- 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.Analysis.Shape
- import Data.Array.Accelerate.CUDA.CodeGen
- import Data.Array.Accelerate.Array.Representation
- import qualified Data.Array.Accelerate.Array.Sugar as Sugar
- #include "accelerate.h"
- type AccKey = ByteString
- -- | Reimplementation of Data.HashTable.hashString to fold over a lazy
- -- bytestring rather than a list of characters.
- --
- hashAccKey :: AccKey -> Int32
- hashAccKey = L.foldl' f golden
- where
- f m c = fromIntegral (ord c) * magic + Hash.hashInt (fromIntegral m)
- magic = 0xdeadbeef
- golden = 1013904242 -- = round ((sqrt 5 - 1) * 2^32)
- -- | Generate a unique key for each kernel computation
- --
- accToKey :: OpenAcc aenv a -> AccKey
- accToKey acc =
- let key = compress . L.pack $ showAcc acc
- in L.head key `seq` key
- -- The first radical identifies the skeleton type (actually, this is arithmetic
- -- sequence A000978), followed by the salient features that parameterise
- -- skeleton instantiation.
- --
- showAcc :: OpenAcc aenv a -> String
- showAcc acc@(OpenAcc pacc) =
- case pacc of
- Generate e f -> chr 1 : showExp e ++ showFun f
- Replicate s e a -> chr 3 : showTy (accType a) ++ showExp e ++ showSI s e a acc
- Index s a e -> chr 5 : showTy (accType a) ++ showExp e ++ showSI s e acc a
- Map f a -> chr 7 : showTy (accType a) ++ showFun f
- ZipWith f x y -> chr 11 : showTy (accType x) ++ showTy (accType y) ++ showFun f
- Fold f e a -> chr 13 : chr (accDim a) : showTy (accType a) ++ showFun f ++ showExp e
- Fold1 f a -> chr 17 : chr (accDim a) : showTy (accType a) ++ showFun f
- FoldSeg f e a _ -> chr 19 : chr (accDim a) : showTy (accType a) ++ showFun f ++ showExp e
- Fold1Seg f a _ -> chr 23 : chr (accDim a) : showTy (accType a) ++ showFun f
- Scanl f e a -> chr 31 : showTy (accType a) ++ showFun f ++ showExp e
- Scanl' f e a -> chr 43 : showTy (accType a) ++ showFun f ++ showExp e
- Scanl1 f a -> chr 61 : showTy (accType a) ++ showFun f
- Scanr f e a -> chr 79 : showTy (accType a) ++ showFun f ++ showExp e
- Scanr' f e a -> chr 101 : showTy (accType a) ++ showFun f ++ showExp e
- Scanr1 f a -> chr 127 : showTy (accType a) ++ showFun f
- Permute c _ p a -> chr 167 : showTy (accType a) ++ showFun c ++ showFun p
- Backpermute _ p a -> chr 191 : showTy (accType a) ++ showFun p
- Stencil f _ a -> chr 199 : showTy (accType a) ++ showFun f
- Stencil2 f _ x _ y -> chr 313 : showTy (accType x) ++ showTy (accType y) ++ showFun f
- _ ->
- let msg = unlines ["incomplete patterns for key generation", render (nest 2 doc)]
- ppr = show acc
- doc | length ppr <= 250 = text ppr
- | otherwise = text (take 250 ppr) <+> text "... {truncated}"
- in
- INTERNAL_ERROR(error) "accToKey" msg
- where
- showTy :: TupleType a -> String
- showTy UnitTuple = []
- showTy (SingleTuple ty) = show ty
- showTy (PairTuple a b) = showTy a ++ showTy b
- showFun :: OpenFun env aenv a -> String
- showFun = render . hcat . map pretty . codeGenFun
- showExp :: OpenExp env aenv a -> String
- showExp = render . hcat . map pretty . codeGenExp
- showSI :: SliceIndex (Sugar.EltRepr slix) (Sugar.EltRepr sl) co (Sugar.EltRepr dim)
- -> Exp aenv slix {- dummy -}
- -> OpenAcc aenv (Sugar.Array sl e) {- dummy -}
- -> OpenAcc aenv (Sugar.Array dim e) {- dummy -}
- -> String
- showSI sl _ _ _ = slice sl 0
- where
- slice :: SliceIndex slix sl co dim -> Int -> String
- slice (SliceNil) _ = []
- slice (SliceAll sliceIdx) n = '_' : slice sliceIdx n
- slice (SliceFixed sliceIdx) n = show n ++ slice sliceIdx (n+1)
- {-
- -- 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 -> Int32
- quad (c1:c2:c3:c4:s) = (( ord' c4 * bits21
- + ord' c3 * bits14
- + ord' c2 * bits7
- + ord' c1)
- `mod` bits28)
- + (quad s `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
- ord' :: Char -> Int32
- ord' = fromIntegral . ord
- bits7, bits14, bits21, bits28 :: Int32
- bits7 = 2^(7 ::Int32)
- bits14 = 2^(14::Int32)
- bits21 = 2^(21::Int32)
- bits28 = 2^(28::Int32)
- -}