-- | 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 (..),
    KernelTarget (..),
    module Futhark.CodeGen.ImpCode.Kernels,
  )
where

import Data.Map qualified as M
import Data.Text qualified as T
import Futhark.CodeGen.ImpCode.Kernels

-- | A program calling OpenCL kernels.
data Program = Program
  { Program -> Text
openClProgram :: T.Text,
    -- | Must be prepended to the program.
    Program -> Text
openClPrelude :: T.Text,
    -- | Definitions to be passed as macro definitions to the kernel
    -- compiler.
    Program -> [(Name, KernelConstExp)]
openClMacroDefs :: [(Name, KernelConstExp)],
    Program -> Map Name KernelSafety
openClKernelNames :: M.Map KernelName KernelSafety,
    -- | So we can detect whether the device is capable.
    Program -> [PrimType]
openClUsedTypes :: [PrimType],
    -- | Assertion failure error messages.
    Program -> [FailureMsg]
openClFailures :: [FailureMsg],
    Program -> Definitions HostOp
hostDefinitions :: Definitions HostOp
  }

-- | The target platform when compiling imperative code to a 'Program'
data KernelTarget
  = TargetOpenCL
  | TargetCUDA
  | TargetHIP
  deriving (KernelTarget -> KernelTarget -> Bool
(KernelTarget -> KernelTarget -> Bool)
-> (KernelTarget -> KernelTarget -> Bool) -> Eq KernelTarget
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: KernelTarget -> KernelTarget -> Bool
== :: KernelTarget -> KernelTarget -> Bool
$c/= :: KernelTarget -> KernelTarget -> Bool
/= :: KernelTarget -> KernelTarget -> Bool
Eq)