-- | In the context of this module, a "size" is any kind of tunable -- (run-time) constant. module Futhark.IR.GPU.Sizes ( SizeClass (..), sizeDefault, KernelPath, Count (..), NumBlocks, BlockSize, NumThreads, ) where import Data.Int (Int64) import Data.Traversable import Futhark.IR.Prop.Names (FreeIn) import Futhark.Transform.Substitute import Futhark.Util.IntegralExp (IntegralExp) import Futhark.Util.Pretty import Language.Futhark.Core (Name) import Prelude hiding (id, (.)) -- | An indication of which comparisons have been performed to get to -- this point, as well as the result of each comparison. type KernelPath = [(Name, Bool)] -- | The class of some kind of configurable size. Each class may -- impose constraints on the valid values. data SizeClass = -- | A threshold with an optional default. SizeThreshold KernelPath (Maybe Int64) | SizeThreadBlock | -- | The number of thread blocks. SizeGrid | SizeTile | SizeRegTile | -- | Likely not useful on its own, but querying the -- maximum can be handy. SizeSharedMemory | -- | A bespoke size with a default. SizeBespoke Name Int64 | -- | Amount of registers available per threadblock. Mostly -- meaningful for querying the maximum. SizeRegisters | -- | Amount of L2 cache memory, in bytes. Mostly meaningful for -- querying the maximum. SizeCache deriving (Eq, Ord, Show) instance Pretty SizeClass where pretty (SizeThreshold path def) = "threshold" <> parens (def' <> comma <+> hsep (map pStep path)) where pStep (v, True) = pretty v pStep (v, False) = "!" <> pretty v def' = maybe "def" pretty def pretty SizeThreadBlock = "thread_block_size" pretty SizeGrid = "grid_size" pretty SizeTile = "tile_size" pretty SizeRegTile = "reg_tile_size" pretty SizeSharedMemory = "shared_memory" pretty (SizeBespoke k def) = "bespoke" <> parens (pretty k <> comma <+> pretty def) pretty SizeRegisters = "registers" pretty SizeCache = "cache" -- | The default value for the size. If 'Nothing', that means the backend gets to decide. sizeDefault :: SizeClass -> Maybe Int64 sizeDefault (SizeThreshold _ x) = x sizeDefault (SizeBespoke _ x) = Just x sizeDefault _ = Nothing -- | A wrapper supporting a phantom type for indicating what we are counting. newtype Count u e = Count {unCount :: e} deriving (Eq, Ord, Show, Num, IntegralExp, FreeIn, Pretty, Substitute) instance Functor (Count u) where fmap = fmapDefault instance Foldable (Count u) where foldMap = foldMapDefault instance Traversable (Count u) where traverse f (Count x) = Count <$> f x -- | Phantom type for the number of blocks of some kernel. data NumBlocks -- | Phantom type for the block size of some kernel. data BlockSize -- | Phantom type for number of threads. data NumThreads