{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Trustworthy #-}

-- | In the context of this module, a "size" is any kind of tunable
-- (run-time) constant.
module Futhark.IR.Kernels.Sizes
  ( SizeClass (..),
    sizeDefault,
    KernelPath,
    Count (..),
    NumGroups,
    GroupSize,
    NumThreads,
  )
where

import Control.Category
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 GHC.Generics (Generic)
import Language.Futhark.Core (Name)
import Language.SexpGrammar as Sexp
import Language.SexpGrammar.Generic
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)
  | SizeGroup
  | SizeNumGroups
  | SizeTile
  | -- | Likely not useful on its own, but querying the
    -- maximum can be handy.
    SizeLocalMemory
  | -- | A bespoke size with a default.
    SizeBespoke Name Int64
  deriving (SizeClass -> SizeClass -> Bool
(SizeClass -> SizeClass -> Bool)
-> (SizeClass -> SizeClass -> Bool) -> Eq SizeClass
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SizeClass -> SizeClass -> Bool
$c/= :: SizeClass -> SizeClass -> Bool
== :: SizeClass -> SizeClass -> Bool
$c== :: SizeClass -> SizeClass -> Bool
Eq, Eq SizeClass
Eq SizeClass
-> (SizeClass -> SizeClass -> Ordering)
-> (SizeClass -> SizeClass -> Bool)
-> (SizeClass -> SizeClass -> Bool)
-> (SizeClass -> SizeClass -> Bool)
-> (SizeClass -> SizeClass -> Bool)
-> (SizeClass -> SizeClass -> SizeClass)
-> (SizeClass -> SizeClass -> SizeClass)
-> Ord SizeClass
SizeClass -> SizeClass -> Bool
SizeClass -> SizeClass -> Ordering
SizeClass -> SizeClass -> SizeClass
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SizeClass -> SizeClass -> SizeClass
$cmin :: SizeClass -> SizeClass -> SizeClass
max :: SizeClass -> SizeClass -> SizeClass
$cmax :: SizeClass -> SizeClass -> SizeClass
>= :: SizeClass -> SizeClass -> Bool
$c>= :: SizeClass -> SizeClass -> Bool
> :: SizeClass -> SizeClass -> Bool
$c> :: SizeClass -> SizeClass -> Bool
<= :: SizeClass -> SizeClass -> Bool
$c<= :: SizeClass -> SizeClass -> Bool
< :: SizeClass -> SizeClass -> Bool
$c< :: SizeClass -> SizeClass -> Bool
compare :: SizeClass -> SizeClass -> Ordering
$ccompare :: SizeClass -> SizeClass -> Ordering
$cp1Ord :: Eq SizeClass
Ord, Int -> SizeClass -> ShowS
[SizeClass] -> ShowS
SizeClass -> String
(Int -> SizeClass -> ShowS)
-> (SizeClass -> String)
-> ([SizeClass] -> ShowS)
-> Show SizeClass
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SizeClass] -> ShowS
$cshowList :: [SizeClass] -> ShowS
show :: SizeClass -> String
$cshow :: SizeClass -> String
showsPrec :: Int -> SizeClass -> ShowS
$cshowsPrec :: Int -> SizeClass -> ShowS
Show, (forall x. SizeClass -> Rep SizeClass x)
-> (forall x. Rep SizeClass x -> SizeClass) -> Generic SizeClass
forall x. Rep SizeClass x -> SizeClass
forall x. SizeClass -> Rep SizeClass x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SizeClass x -> SizeClass
$cfrom :: forall x. SizeClass -> Rep SizeClass x
Generic)

instance SexpIso SizeClass where
  sexpIso :: Grammar Position (Sexp :- t) (SizeClass :- t)
sexpIso =
    Coproduct
  Position
  (Sexp :- t)
  '[Maybe Int64 :- ([(Name, Bool)] :- t), t, t, t, t,
    Int64 :- (Name :- t)]
  SizeClass
  t
-> Grammar Position (Sexp :- t) (SizeClass :- t)
forall a (bs :: [*]) t p s.
(Generic a, MkPrismList (Rep a), Match (Rep a) bs t,
 bs ~ Coll (Rep a) t) =>
Coproduct p s bs a t -> Grammar p s (a :- t)
match (Coproduct
   Position
   (Sexp :- t)
   '[Maybe Int64 :- ([(Name, Bool)] :- t), t, t, t, t,
     Int64 :- (Name :- t)]
   SizeClass
   t
 -> Grammar Position (Sexp :- t) (SizeClass :- t))
-> Coproduct
     Position
     (Sexp :- t)
     '[Maybe Int64 :- ([(Name, Bool)] :- t), t, t, t, t,
       Int64 :- (Name :- t)]
     SizeClass
     t
-> Grammar Position (Sexp :- t) (SizeClass :- t)
forall a b. (a -> b) -> a -> b
$
      (Grammar
   Position (Maybe Int64 :- ([(Name, Bool)] :- t)) (SizeClass :- t)
 -> Grammar Position (Sexp :- t) (SizeClass :- t))
-> Coproduct
     Position
     (Sexp :- t)
     '[t, t, t, t, Int64 :- (Name :- t)]
     SizeClass
     t
-> Coproduct
     Position
     (Sexp :- t)
     '[Maybe Int64 :- ([(Name, Bool)] :- t), t, t, t, t,
       Int64 :- (Name :- t)]
     SizeClass
     t
forall p b a t s (bs1 :: [*]).
(Grammar p b (a :- t) -> Grammar p s (a :- t))
-> Coproduct p s bs1 a t -> Coproduct p s (b : bs1) a t
With (Grammar
  Position (Maybe Int64 :- ([(Name, Bool)] :- t)) (SizeClass :- t)
-> Grammar
     Position (Sexp :- t) (Maybe Int64 :- ([(Name, Bool)] :- t))
-> Grammar Position (Sexp :- t) (SizeClass :- t)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Grammar
  Position
  (List :- t)
  (List :- (Maybe Int64 :- ([(Name, Bool)] :- t)))
-> Grammar
     Position (Sexp :- t) (Maybe Int64 :- ([(Name, Bool)] :- t))
forall t t'.
Grammar Position (List :- t) (List :- t')
-> Grammar Position (Sexp :- t) t'
Sexp.list (Grammar Position (Sexp :- t) t
-> Grammar Position (List :- t) (List :- t)
forall t t'.
Grammar Position (Sexp :- t) t'
-> Grammar Position (List :- t) (List :- t')
Sexp.el (Text -> Grammar Position (Sexp :- t) t
forall t. Text -> Grammar Position (Sexp :- t) t
Sexp.sym Text
"threshold") Grammar Position (List :- t) (List :- t)
-> Grammar
     Position
     (List :- t)
     (List :- (Maybe Int64 :- ([(Name, Bool)] :- t)))
-> Grammar
     Position
     (List :- t)
     (List :- (Maybe Int64 :- ([(Name, Bool)] :- t)))
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Grammar Position (Sexp :- t) ([(Name, Bool)] :- t)
-> Grammar Position (List :- t) (List :- ([(Name, Bool)] :- t))
forall t t'.
Grammar Position (Sexp :- t) t'
-> Grammar Position (List :- t) (List :- t')
Sexp.el Grammar Position (Sexp :- t) ([(Name, Bool)] :- t)
forall a. SexpIso a => SexpGrammar a
sexpIso Grammar Position (List :- t) (List :- ([(Name, Bool)] :- t))
-> Grammar
     Position
     (List :- ([(Name, Bool)] :- t))
     (List :- (Maybe Int64 :- ([(Name, Bool)] :- t)))
-> Grammar
     Position
     (List :- t)
     (List :- (Maybe Int64 :- ([(Name, Bool)] :- t)))
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Grammar
  Position
  (PropertyList :- ([(Name, Bool)] :- t))
  (PropertyList :- (Maybe Int64 :- ([(Name, Bool)] :- t)))
-> Grammar
     Position
     (List :- ([(Name, Bool)] :- t))
     (List :- (Maybe Int64 :- ([(Name, Bool)] :- t)))
forall t t'.
Grammar Position (PropertyList :- t) (PropertyList :- t')
-> Grammar Position (List :- t) (List :- t')
props (Text
-> (forall t1. Grammar Position (Sexp :- t1) (Int64 :- t1))
-> Grammar
     Position
     (PropertyList :- ([(Name, Bool)] :- t))
     (PropertyList :- (Maybe Int64 :- ([(Name, Bool)] :- t)))
forall a t.
Text
-> (forall t1. Grammar Position (Sexp :- t1) (a :- t1))
-> Grammar
     Position (PropertyList :- t) (PropertyList :- (Maybe a :- t))
Sexp.optKey Text
"default" ((Int -> Int64)
-> (Int64 -> Int) -> Grammar Position (Int :- t1) (Int64 :- t1)
forall a b p t. (a -> b) -> (b -> a) -> Grammar p (a :- t) (b :- t)
iso Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Grammar Position (Int :- t1) (Int64 :- t1)
-> Grammar Position (Sexp :- t1) (Int :- t1)
-> Grammar Position (Sexp :- t1) (Int64 :- t1)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Grammar Position (Sexp :- t1) (Int :- t1)
forall t. Grammar Position (Sexp :- t) (Int :- t)
Sexp.int)))) (Coproduct
   Position
   (Sexp :- t)
   '[t, t, t, t, Int64 :- (Name :- t)]
   SizeClass
   t
 -> Coproduct
      Position
      (Sexp :- t)
      '[Maybe Int64 :- ([(Name, Bool)] :- t), t, t, t, t,
        Int64 :- (Name :- t)]
      SizeClass
      t)
-> Coproduct
     Position
     (Sexp :- t)
     '[t, t, t, t, Int64 :- (Name :- t)]
     SizeClass
     t
-> Coproduct
     Position
     (Sexp :- t)
     '[Maybe Int64 :- ([(Name, Bool)] :- t), t, t, t, t,
       Int64 :- (Name :- t)]
     SizeClass
     t
forall a b. (a -> b) -> a -> b
$
        (Grammar Position t (SizeClass :- t)
 -> Grammar Position (Sexp :- t) (SizeClass :- t))
-> Coproduct
     Position (Sexp :- t) '[t, t, t, Int64 :- (Name :- t)] SizeClass t
-> Coproduct
     Position
     (Sexp :- t)
     '[t, t, t, t, Int64 :- (Name :- t)]
     SizeClass
     t
forall p b a t s (bs1 :: [*]).
(Grammar p b (a :- t) -> Grammar p s (a :- t))
-> Coproduct p s bs1 a t -> Coproduct p s (b : bs1) a t
With (Grammar Position t (SizeClass :- t)
-> Grammar Position (Sexp :- t) t
-> Grammar Position (Sexp :- t) (SizeClass :- t)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Text -> Grammar Position (Sexp :- t) t
forall t. Text -> Grammar Position (Sexp :- t) t
Sexp.sym Text
"group") (Coproduct
   Position (Sexp :- t) '[t, t, t, Int64 :- (Name :- t)] SizeClass t
 -> Coproduct
      Position
      (Sexp :- t)
      '[t, t, t, t, Int64 :- (Name :- t)]
      SizeClass
      t)
-> Coproduct
     Position (Sexp :- t) '[t, t, t, Int64 :- (Name :- t)] SizeClass t
-> Coproduct
     Position
     (Sexp :- t)
     '[t, t, t, t, Int64 :- (Name :- t)]
     SizeClass
     t
forall a b. (a -> b) -> a -> b
$
          (Grammar Position t (SizeClass :- t)
 -> Grammar Position (Sexp :- t) (SizeClass :- t))
-> Coproduct
     Position (Sexp :- t) '[t, t, Int64 :- (Name :- t)] SizeClass t
-> Coproduct
     Position (Sexp :- t) '[t, t, t, Int64 :- (Name :- t)] SizeClass t
forall p b a t s (bs1 :: [*]).
(Grammar p b (a :- t) -> Grammar p s (a :- t))
-> Coproduct p s bs1 a t -> Coproduct p s (b : bs1) a t
With (Grammar Position t (SizeClass :- t)
-> Grammar Position (Sexp :- t) t
-> Grammar Position (Sexp :- t) (SizeClass :- t)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Text -> Grammar Position (Sexp :- t) t
forall t. Text -> Grammar Position (Sexp :- t) t
Sexp.sym Text
"num-groups") (Coproduct
   Position (Sexp :- t) '[t, t, Int64 :- (Name :- t)] SizeClass t
 -> Coproduct
      Position (Sexp :- t) '[t, t, t, Int64 :- (Name :- t)] SizeClass t)
-> Coproduct
     Position (Sexp :- t) '[t, t, Int64 :- (Name :- t)] SizeClass t
-> Coproduct
     Position (Sexp :- t) '[t, t, t, Int64 :- (Name :- t)] SizeClass t
forall a b. (a -> b) -> a -> b
$
            (Grammar Position t (SizeClass :- t)
 -> Grammar Position (Sexp :- t) (SizeClass :- t))
-> Coproduct
     Position (Sexp :- t) '[t, Int64 :- (Name :- t)] SizeClass t
-> Coproduct
     Position (Sexp :- t) '[t, t, Int64 :- (Name :- t)] SizeClass t
forall p b a t s (bs1 :: [*]).
(Grammar p b (a :- t) -> Grammar p s (a :- t))
-> Coproduct p s bs1 a t -> Coproduct p s (b : bs1) a t
With (Grammar Position t (SizeClass :- t)
-> Grammar Position (Sexp :- t) t
-> Grammar Position (Sexp :- t) (SizeClass :- t)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Text -> Grammar Position (Sexp :- t) t
forall t. Text -> Grammar Position (Sexp :- t) t
Sexp.sym Text
"tile") (Coproduct
   Position (Sexp :- t) '[t, Int64 :- (Name :- t)] SizeClass t
 -> Coproduct
      Position (Sexp :- t) '[t, t, Int64 :- (Name :- t)] SizeClass t)
-> Coproduct
     Position (Sexp :- t) '[t, Int64 :- (Name :- t)] SizeClass t
-> Coproduct
     Position (Sexp :- t) '[t, t, Int64 :- (Name :- t)] SizeClass t
forall a b. (a -> b) -> a -> b
$
              (Grammar Position t (SizeClass :- t)
 -> Grammar Position (Sexp :- t) (SizeClass :- t))
-> Coproduct
     Position (Sexp :- t) '[Int64 :- (Name :- t)] SizeClass t
-> Coproduct
     Position (Sexp :- t) '[t, Int64 :- (Name :- t)] SizeClass t
forall p b a t s (bs1 :: [*]).
(Grammar p b (a :- t) -> Grammar p s (a :- t))
-> Coproduct p s bs1 a t -> Coproduct p s (b : bs1) a t
With (Grammar Position t (SizeClass :- t)
-> Grammar Position (Sexp :- t) t
-> Grammar Position (Sexp :- t) (SizeClass :- t)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Text -> Grammar Position (Sexp :- t) t
forall t. Text -> Grammar Position (Sexp :- t) t
Sexp.sym Text
"local-memory") (Coproduct Position (Sexp :- t) '[Int64 :- (Name :- t)] SizeClass t
 -> Coproduct
      Position (Sexp :- t) '[t, Int64 :- (Name :- t)] SizeClass t)
-> Coproduct
     Position (Sexp :- t) '[Int64 :- (Name :- t)] SizeClass t
-> Coproduct
     Position (Sexp :- t) '[t, Int64 :- (Name :- t)] SizeClass t
forall a b. (a -> b) -> a -> b
$
                (Grammar Position (Int64 :- (Name :- t)) (SizeClass :- t)
 -> Grammar Position (Sexp :- t) (SizeClass :- t))
-> Coproduct Position (Sexp :- t) '[] SizeClass t
-> Coproduct
     Position (Sexp :- t) '[Int64 :- (Name :- t)] SizeClass t
forall p b a t s (bs1 :: [*]).
(Grammar p b (a :- t) -> Grammar p s (a :- t))
-> Coproduct p s bs1 a t -> Coproduct p s (b : bs1) a t
With
                  (Grammar Position (Int64 :- (Name :- t)) (SizeClass :- t)
-> Grammar Position (Sexp :- t) (Int64 :- (Name :- t))
-> Grammar Position (Sexp :- t) (SizeClass :- t)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Grammar Position (List :- t) (List :- (Int64 :- (Name :- t)))
-> Grammar Position (Sexp :- t) (Int64 :- (Name :- t))
forall t t'.
Grammar Position (List :- t) (List :- t')
-> Grammar Position (Sexp :- t) t'
Sexp.list (Grammar Position (Sexp :- t) t
-> Grammar Position (List :- t) (List :- t)
forall t t'.
Grammar Position (Sexp :- t) t'
-> Grammar Position (List :- t) (List :- t')
Sexp.el (Text -> Grammar Position (Sexp :- t) t
forall t. Text -> Grammar Position (Sexp :- t) t
Sexp.sym Text
"bespoke") Grammar Position (List :- t) (List :- t)
-> Grammar Position (List :- t) (List :- (Int64 :- (Name :- t)))
-> Grammar Position (List :- t) (List :- (Int64 :- (Name :- t)))
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Grammar Position (Sexp :- t) (Name :- t)
-> Grammar Position (List :- t) (List :- (Name :- t))
forall t t'.
Grammar Position (Sexp :- t) t'
-> Grammar Position (List :- t) (List :- t')
Sexp.el Grammar Position (Sexp :- t) (Name :- t)
forall a. SexpIso a => SexpGrammar a
sexpIso Grammar Position (List :- t) (List :- (Name :- t))
-> Grammar
     Position (List :- (Name :- t)) (List :- (Int64 :- (Name :- t)))
-> Grammar Position (List :- t) (List :- (Int64 :- (Name :- t)))
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Grammar Position (Sexp :- (Name :- t)) (Int64 :- (Name :- t))
-> Grammar
     Position (List :- (Name :- t)) (List :- (Int64 :- (Name :- t)))
forall t t'.
Grammar Position (Sexp :- t) t'
-> Grammar Position (List :- t) (List :- t')
Sexp.el ((Int -> Int64)
-> (Int64 -> Int)
-> Grammar Position (Int :- (Name :- t)) (Int64 :- (Name :- t))
forall a b p t. (a -> b) -> (b -> a) -> Grammar p (a :- t) (b :- t)
iso Int -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Grammar Position (Int :- (Name :- t)) (Int64 :- (Name :- t))
-> Grammar Position (Sexp :- (Name :- t)) (Int :- (Name :- t))
-> Grammar Position (Sexp :- (Name :- t)) (Int64 :- (Name :- t))
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Grammar Position (Sexp :- (Name :- t)) (Int :- (Name :- t))
forall t. Grammar Position (Sexp :- t) (Int :- t)
Sexp.int)))
                  Coproduct Position (Sexp :- t) '[] SizeClass t
forall p s a t. Coproduct p s '[] a t
End

instance Pretty SizeClass where
  ppr :: SizeClass -> Doc
ppr (SizeThreshold [(Name, Bool)]
path Maybe Int64
_) = String -> Doc
text (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ String
"threshold (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ [String] -> String
unwords (((Name, Bool) -> String) -> [(Name, Bool)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Name, Bool) -> String
forall a. Pretty a => (a, Bool) -> String
pStep [(Name, Bool)]
path) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
    where
      pStep :: (a, Bool) -> String
pStep (a
v, Bool
True) = a -> String
forall a. Pretty a => a -> String
pretty a
v
      pStep (a
v, Bool
False) = Char
'!' Char -> ShowS
forall a. a -> [a] -> [a]
: a -> String
forall a. Pretty a => a -> String
pretty a
v
  ppr SizeClass
SizeGroup = String -> Doc
text String
"group_size"
  ppr SizeClass
SizeNumGroups = String -> Doc
text String
"num_groups"
  ppr SizeClass
SizeTile = String -> Doc
text String
"tile_size"
  ppr SizeClass
SizeLocalMemory = String -> Doc
text String
"local_memory"
  ppr (SizeBespoke Name
k Int64
_) = Name -> Doc
forall a. Pretty a => a -> Doc
ppr Name
k

-- | The default value for the size.  If 'Nothing', that means the backend gets to decide.
sizeDefault :: SizeClass -> Maybe Int64
sizeDefault :: SizeClass -> Maybe Int64
sizeDefault (SizeThreshold [(Name, Bool)]
_ Maybe Int64
x) = Maybe Int64
x
sizeDefault (SizeBespoke Name
_ Int64
x) = Int64 -> Maybe Int64
forall a. a -> Maybe a
Just Int64
x
sizeDefault SizeClass
_ = Maybe Int64
forall a. Maybe a
Nothing

-- | A wrapper supporting a phantom type for indicating what we are counting.
newtype Count u e = Count {Count u e -> e
unCount :: e}
  deriving (Count u e -> Count u e -> Bool
(Count u e -> Count u e -> Bool)
-> (Count u e -> Count u e -> Bool) -> Eq (Count u e)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall u e. Eq e => Count u e -> Count u e -> Bool
/= :: Count u e -> Count u e -> Bool
$c/= :: forall u e. Eq e => Count u e -> Count u e -> Bool
== :: Count u e -> Count u e -> Bool
$c== :: forall u e. Eq e => Count u e -> Count u e -> Bool
Eq, Eq (Count u e)
Eq (Count u e)
-> (Count u e -> Count u e -> Ordering)
-> (Count u e -> Count u e -> Bool)
-> (Count u e -> Count u e -> Bool)
-> (Count u e -> Count u e -> Bool)
-> (Count u e -> Count u e -> Bool)
-> (Count u e -> Count u e -> Count u e)
-> (Count u e -> Count u e -> Count u e)
-> Ord (Count u e)
Count u e -> Count u e -> Bool
Count u e -> Count u e -> Ordering
Count u e -> Count u e -> Count u e
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall u e. Ord e => Eq (Count u e)
forall u e. Ord e => Count u e -> Count u e -> Bool
forall u e. Ord e => Count u e -> Count u e -> Ordering
forall u e. Ord e => Count u e -> Count u e -> Count u e
min :: Count u e -> Count u e -> Count u e
$cmin :: forall u e. Ord e => Count u e -> Count u e -> Count u e
max :: Count u e -> Count u e -> Count u e
$cmax :: forall u e. Ord e => Count u e -> Count u e -> Count u e
>= :: Count u e -> Count u e -> Bool
$c>= :: forall u e. Ord e => Count u e -> Count u e -> Bool
> :: Count u e -> Count u e -> Bool
$c> :: forall u e. Ord e => Count u e -> Count u e -> Bool
<= :: Count u e -> Count u e -> Bool
$c<= :: forall u e. Ord e => Count u e -> Count u e -> Bool
< :: Count u e -> Count u e -> Bool
$c< :: forall u e. Ord e => Count u e -> Count u e -> Bool
compare :: Count u e -> Count u e -> Ordering
$ccompare :: forall u e. Ord e => Count u e -> Count u e -> Ordering
$cp1Ord :: forall u e. Ord e => Eq (Count u e)
Ord, Int -> Count u e -> ShowS
[Count u e] -> ShowS
Count u e -> String
(Int -> Count u e -> ShowS)
-> (Count u e -> String)
-> ([Count u e] -> ShowS)
-> Show (Count u e)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall u e. Show e => Int -> Count u e -> ShowS
forall u e. Show e => [Count u e] -> ShowS
forall u e. Show e => Count u e -> String
showList :: [Count u e] -> ShowS
$cshowList :: forall u e. Show e => [Count u e] -> ShowS
show :: Count u e -> String
$cshow :: forall u e. Show e => Count u e -> String
showsPrec :: Int -> Count u e -> ShowS
$cshowsPrec :: forall u e. Show e => Int -> Count u e -> ShowS
Show, Integer -> Count u e
Count u e -> Count u e
Count u e -> Count u e -> Count u e
(Count u e -> Count u e -> Count u e)
-> (Count u e -> Count u e -> Count u e)
-> (Count u e -> Count u e -> Count u e)
-> (Count u e -> Count u e)
-> (Count u e -> Count u e)
-> (Count u e -> Count u e)
-> (Integer -> Count u e)
-> Num (Count u e)
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
forall u e. Num e => Integer -> Count u e
forall u e. Num e => Count u e -> Count u e
forall u e. Num e => Count u e -> Count u e -> Count u e
fromInteger :: Integer -> Count u e
$cfromInteger :: forall u e. Num e => Integer -> Count u e
signum :: Count u e -> Count u e
$csignum :: forall u e. Num e => Count u e -> Count u e
abs :: Count u e -> Count u e
$cabs :: forall u e. Num e => Count u e -> Count u e
negate :: Count u e -> Count u e
$cnegate :: forall u e. Num e => Count u e -> Count u e
* :: Count u e -> Count u e -> Count u e
$c* :: forall u e. Num e => Count u e -> Count u e -> Count u e
- :: Count u e -> Count u e -> Count u e
$c- :: forall u e. Num e => Count u e -> Count u e -> Count u e
+ :: Count u e -> Count u e -> Count u e
$c+ :: forall u e. Num e => Count u e -> Count u e -> Count u e
Num, Num (Count u e)
Num (Count u e)
-> (Count u e -> Count u e -> Count u e)
-> (Count u e -> Count u e -> Count u e)
-> (Count u e -> Count u e -> Count u e)
-> (Count u e -> Count u e -> Count u e)
-> (Count u e -> Maybe Int)
-> (Count u e -> Count u e -> Count u e)
-> IntegralExp (Count u e)
Count u e -> Maybe Int
Count u e -> Count u e -> Count u e
forall e.
Num e
-> (e -> e -> e)
-> (e -> e -> e)
-> (e -> e -> e)
-> (e -> e -> e)
-> (e -> Maybe Int)
-> (e -> e -> e)
-> IntegralExp e
forall u e. IntegralExp e => Num (Count u e)
forall u e. IntegralExp e => Count u e -> Maybe Int
forall u e. IntegralExp e => Count u e -> Count u e -> Count u e
divUp :: Count u e -> Count u e -> Count u e
$cdivUp :: forall u e. IntegralExp e => Count u e -> Count u e -> Count u e
sgn :: Count u e -> Maybe Int
$csgn :: forall u e. IntegralExp e => Count u e -> Maybe Int
mod :: Count u e -> Count u e -> Count u e
$cmod :: forall u e. IntegralExp e => Count u e -> Count u e -> Count u e
div :: Count u e -> Count u e -> Count u e
$cdiv :: forall u e. IntegralExp e => Count u e -> Count u e -> Count u e
rem :: Count u e -> Count u e -> Count u e
$crem :: forall u e. IntegralExp e => Count u e -> Count u e -> Count u e
quot :: Count u e -> Count u e -> Count u e
$cquot :: forall u e. IntegralExp e => Count u e -> Count u e -> Count u e
$cp1IntegralExp :: forall u e. IntegralExp e => Num (Count u e)
IntegralExp, Count u e -> FV
(Count u e -> FV) -> FreeIn (Count u e)
forall a. (a -> FV) -> FreeIn a
forall u e. FreeIn e => Count u e -> FV
freeIn' :: Count u e -> FV
$cfreeIn' :: forall u e. FreeIn e => Count u e -> FV
FreeIn, Int -> Count u e -> Doc
[Count u e] -> Doc
Count u e -> Doc
(Count u e -> Doc)
-> (Int -> Count u e -> Doc)
-> ([Count u e] -> Doc)
-> Pretty (Count u e)
forall a.
(a -> Doc) -> (Int -> a -> Doc) -> ([a] -> Doc) -> Pretty a
forall u e. Pretty e => Int -> Count u e -> Doc
forall u e. Pretty e => [Count u e] -> Doc
forall u e. Pretty e => Count u e -> Doc
pprList :: [Count u e] -> Doc
$cpprList :: forall u e. Pretty e => [Count u e] -> Doc
pprPrec :: Int -> Count u e -> Doc
$cpprPrec :: forall u e. Pretty e => Int -> Count u e -> Doc
ppr :: Count u e -> Doc
$cppr :: forall u e. Pretty e => Count u e -> Doc
Pretty, Map VName VName -> Count u e -> Count u e
(Map VName VName -> Count u e -> Count u e)
-> Substitute (Count u e)
forall a. (Map VName VName -> a -> a) -> Substitute a
forall u e.
Substitute e =>
Map VName VName -> Count u e -> Count u e
substituteNames :: Map VName VName -> Count u e -> Count u e
$csubstituteNames :: forall u e.
Substitute e =>
Map VName VName -> Count u e -> Count u e
Substitute, (forall x. Count u e -> Rep (Count u e) x)
-> (forall x. Rep (Count u e) x -> Count u e)
-> Generic (Count u e)
forall x. Rep (Count u e) x -> Count u e
forall x. Count u e -> Rep (Count u e) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall u e x. Rep (Count u e) x -> Count u e
forall u e x. Count u e -> Rep (Count u e) x
$cto :: forall u e x. Rep (Count u e) x -> Count u e
$cfrom :: forall u e x. Count u e -> Rep (Count u e) x
Generic)

instance SexpIso e => SexpIso (Count u e) where
  sexpIso :: Grammar Position (Sexp :- t) (Count u e :- t)
sexpIso = (Grammar Position (e :- t) (Count u e :- t)
 -> Grammar Position (Sexp :- t) (Count u e :- t))
-> Grammar Position (Sexp :- t) (Count u e :- t)
forall a b s t (c :: Meta) (d :: Meta) (f :: * -> *) p.
(Generic a, MkPrismList (Rep a), MkStackPrism f,
 Rep a ~ M1 D d (M1 C c f), StackPrismLhs f t ~ b, Constructor c) =>
(Grammar p b (a :- t) -> Grammar p s (a :- t))
-> Grammar p s (a :- t)
with ((Grammar Position (e :- t) (Count u e :- t)
  -> Grammar Position (Sexp :- t) (Count u e :- t))
 -> Grammar Position (Sexp :- t) (Count u e :- t))
-> (Grammar Position (e :- t) (Count u e :- t)
    -> Grammar Position (Sexp :- t) (Count u e :- t))
-> Grammar Position (Sexp :- t) (Count u e :- t)
forall a b. (a -> b) -> a -> b
$ \Grammar Position (e :- t) (Count u e :- t)
count -> Grammar Position (Sexp :- t) (e :- t)
forall a. SexpIso a => SexpGrammar a
sexpIso Grammar Position (Sexp :- t) (e :- t)
-> Grammar Position (e :- t) (Count u e :- t)
-> Grammar Position (Sexp :- t) (Count u e :- t)
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Grammar Position (e :- t) (Count u e :- t)
count

instance Functor (Count u) where
  fmap :: (a -> b) -> Count u a -> Count u b
fmap = (a -> b) -> Count u a -> Count u b
forall (t :: * -> *) a b. Traversable t => (a -> b) -> t a -> t b
fmapDefault

instance Foldable (Count u) where
  foldMap :: (a -> m) -> Count u a -> m
foldMap = (a -> m) -> Count u a -> m
forall (t :: * -> *) m a.
(Traversable t, Monoid m) =>
(a -> m) -> t a -> m
foldMapDefault

instance Traversable (Count u) where
  traverse :: (a -> f b) -> Count u a -> f (Count u b)
traverse a -> f b
f (Count a
x) = b -> Count u b
forall u e. e -> Count u e
Count (b -> Count u b) -> f b -> f (Count u b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f b
f a
x

-- | Phantom type for the number of groups of some kernel.
data NumGroups

-- | Phantom type for the group size of some kernel.
data GroupSize

-- | Phantom type for number of threads.
data NumThreads