futhark-0.25.11: src/Futhark/CodeGen/ImpCode/OpenCL.hs
-- | Imperative code with an OpenCL component.
--
-- Apart from ordinary imperative code, this also carries around an
-- OpenCL program as a string, as well as a list of kernels defined by
-- the OpenCL program.
--
-- The imperative code has been augmented with a 'LaunchKernel'
-- operation that allows one to execute an OpenCL kernel.
module Futhark.CodeGen.ImpCode.OpenCL
( Program (..),
KernelName,
KernelArg (..),
CLCode,
OpenCL (..),
KernelSafety (..),
numFailureParams,
KernelTarget (..),
FailureMsg (..),
BlockDim,
KernelConst (..),
KernelConstExp,
module Futhark.CodeGen.ImpCode,
module Futhark.IR.GPU.Sizes,
)
where
import Data.Map qualified as M
import Data.Text qualified as T
import Futhark.CodeGen.ImpCode
import Futhark.CodeGen.ImpCode.GPU (BlockDim, KernelConst (..), KernelConstExp)
import Futhark.IR.GPU.Sizes
import Futhark.Util.Pretty
-- | An program calling OpenCL kernels.
data Program = Program
{ openClProgram :: T.Text,
-- | Must be prepended to the program.
openClPrelude :: T.Text,
-- | Definitions to be passed as macro definitions to the kernel
-- compiler.
openClMacroDefs :: [(Name, KernelConstExp)],
openClKernelNames :: M.Map KernelName KernelSafety,
-- | So we can detect whether the device is capable.
openClUsedTypes :: [PrimType],
-- | Runtime-configurable constants.
openClParams :: ParamMap,
-- | Assertion failure error messages.
openClFailures :: [FailureMsg],
hostDefinitions :: Definitions OpenCL
}
-- | Something that can go wrong in a kernel. Part of the machinery
-- for reporting error messages from within kernels.
data FailureMsg = FailureMsg
{ failureError :: ErrorMsg Exp,
failureBacktrace :: String
}
-- | A piece of code calling OpenCL.
type CLCode = Code OpenCL
-- | The name of a kernel.
type KernelName = Name
-- | An argument to be passed to a kernel.
data KernelArg
= -- | Pass the value of this scalar expression as argument.
ValueKArg Exp PrimType
| -- | Pass this pointer as argument.
MemKArg VName
deriving (Show)
-- | Whether a kernel can potentially fail (because it contains bounds
-- checks and such).
data MayFail = MayFail | CannotFail
deriving (Show)
-- | Information about bounds checks and how sensitive it is to
-- errors. Ordered by least demanding to most.
data KernelSafety
= -- | Does not need to know if we are in a failing state, and also
-- cannot fail.
SafetyNone
| -- | Needs to be told if there's a global failure, and that's it,
-- and cannot fail.
SafetyCheap
| -- | Needs all parameters, may fail itself.
SafetyFull
deriving (Eq, Ord, Show)
-- | How many leading failure arguments we must pass when launching a
-- kernel with these safety characteristics.
numFailureParams :: KernelSafety -> Int
numFailureParams SafetyNone = 0
numFailureParams SafetyCheap = 1
numFailureParams SafetyFull = 3
-- | Host-level OpenCL operation.
data OpenCL
= LaunchKernel KernelSafety KernelName (Count Bytes (TExp Int64)) [KernelArg] [Exp] [BlockDim]
| GetSize VName Name
| CmpSizeLe VName Name Exp
| GetSizeMax VName SizeClass
deriving (Show)
-- | The target platform when compiling imperative code to a 'Program'
data KernelTarget
= TargetOpenCL
| TargetCUDA
| TargetHIP
deriving (Eq)
instance Pretty OpenCL where
pretty = pretty . show