{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}

-- |
-- Module      : Language.Halide.Target
-- Description : Compilation targets and their features
-- Copyright   : (c) Tom Westerhout, 2023
--
-- This module defines a data type 'Target' that represents the compilation target.
-- This could be the host target, or a CUDA device with CUDA capability of at least 7,
-- or an OpenCL device, etc.
--
-- You would typically start with 'hostTarget' and then extend it using various 'TargetFeature's.
-- This can be done with the 'setFeature' function.
module Language.Halide.Target
  ( Target (..)
  , hostTarget
  , gpuTarget
  , hostSupportsTargetDevice
  , setFeature
  , hasGpuFeature
  , TargetFeature (..)
  , DeviceAPI (..)
  -- , targetFeatureForDeviceAPI
  , deviceAPIForTarget

    -- * Internal
  , withCxxTarget
  , testCUDA
  , testOpenCL
  )
where

import Data.Text (unpack)
import Foreign.ForeignPtr
import Foreign.Ptr (Ptr)
import GHC.IO (unsafePerformIO)
import Language.C.Inline qualified as C
import Language.C.Inline.Cpp.Exception qualified as C
import Language.C.Inline.Unsafe qualified as CU
import Language.Halide.Context
import Language.Halide.Type
import Language.Halide.Utils
import Prelude hiding (tail)

importHalide

-- | The compilation target.
--
-- This is the Haskell counterpart of [@Halide::Target@](https://halide-lang.org/docs/struct_halide_1_1_target.html).
newtype Target = Target (ForeignPtr CxxTarget)

instance Eq Target where
  == :: Target -> Target -> Bool
(==) Target
target1 Target
target2 =
    forall a. Enum a => Int -> a
toEnum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
      forall a. Target -> (Ptr CxxTarget -> IO a) -> IO a
withCxxTarget Target
target1 forall a b. (a -> b) -> a -> b
$ \Ptr CxxTarget
t1 ->
        forall a. Target -> (Ptr CxxTarget -> IO a) -> IO a
withCxxTarget Target
target2 forall a b. (a -> b) -> a -> b
$ \Ptr CxxTarget
t2 ->
          [CU.exp| bool { *$(const Halide::Target* t1) == *$(const Halide::Target* t2) } |]

instance Show Target where
  show :: Target -> String
show Target
target =
    Text -> String
unpack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a. Target -> (Ptr CxxTarget -> IO a) -> IO a
withCxxTarget Target
target forall a b. (a -> b) -> a -> b
$ \Ptr CxxTarget
t ->
      Ptr CxxString -> IO Text
peekAndDeleteCxxString
        forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [CU.exp| std::string* {
              new std::string{$(const Halide::Target* t)->to_string()} } |]

-- | Return the target that Halide will use by default.
--
-- If the @HL_TARGET@ environment variable is set, it uses that. Otherwise, it
-- returns the target corresponding to the host machine.
hostTarget :: Target
hostTarget :: Target
hostTarget =
  forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
    Ptr CxxTarget -> IO Target
wrapCxxTarget
      forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [CU.exp| Halide::Target* { new Halide::Target{Halide::get_target_from_environment()} } |]
{-# NOINLINE hostTarget #-}

-- | Get the default GPU target. We first check for CUDA and then for OpenCL.
-- If neither of the two is usable, 'Nothing' is returned.
gpuTarget :: Maybe Target
gpuTarget :: Maybe Target
gpuTarget
  | Target -> Bool
hostSupportsTargetDevice Target
cudaTarget = forall a. a -> Maybe a
Just Target
cudaTarget
  | Target -> Bool
hostSupportsTargetDevice Target
openCLTarget = forall a. a -> Maybe a
Just Target
openCLTarget
  | Bool
otherwise = forall a. Maybe a
Nothing
  where
    openCLTarget :: Target
openCLTarget = TargetFeature -> Target -> Target
setFeature TargetFeature
FeatureOpenCL Target
hostTarget
    cudaTarget :: Target
cudaTarget = TargetFeature -> Target -> Target
setFeature TargetFeature
FeatureCUDA Target
hostTarget

-- | Attempt to sniff whether a given 'Target' (and its implied 'DeviceAPI') is usable on the
-- current host.
--
-- __Note__ that a return value of @True@ does not guarantee that future usage of that device will
-- succeed; it is intended mainly as a simple diagnostic to allow early-exit when a desired device
-- is definitely not usable.
--
-- Also note that this call is __NOT threadsafe__, as it temporarily redirects various global
-- error-handling hooks in Halide.
hostSupportsTargetDevice
  :: Target
  -> Bool
  -- ^ Whether the target appears to be usable
hostSupportsTargetDevice :: Target -> Bool
hostSupportsTargetDevice Target
target =
  forall a. IO a -> a
unsafePerformIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. Enum a => Int -> a
toEnum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) forall a b. (a -> b) -> a -> b
$
    forall a. Target -> (Ptr CxxTarget -> IO a) -> IO a
withCxxTarget Target
target forall a b. (a -> b) -> a -> b
$ \Ptr CxxTarget
t ->
      [CU.exp| bool { Halide::host_supports_target_device(*$(Halide::Target* t)) } |]

-- | Add a feature to target.
setFeature
  :: TargetFeature
  -- ^ Feature to add
  -> Target
  -- ^ Initial target
  -> Target
  -- ^ New target
setFeature :: TargetFeature -> Target -> Target
setFeature TargetFeature
feature Target
target = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
  forall a. Target -> (Ptr CxxTarget -> IO a) -> IO a
withCxxTarget Target
target forall a b. (a -> b) -> a -> b
$ \Ptr CxxTarget
t ->
    Ptr CxxTarget -> IO Target
wrapCxxTarget
      forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [CU.exp| Halide::Target* {
            new Halide::Target{$(Halide::Target* t)->with_feature(
              static_cast<Halide::Target::Feature>($(int f)))} 
          } |]
  where
    f :: CInt
f = forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Enum a => a -> Int
fromEnum forall a b. (a -> b) -> a -> b
$ TargetFeature
feature

-- | Return whether a GPU compute runtime is enabled.
--
-- Checks whether 'Language.Halide.Func.gpuBlocks' and similar are going to work.
--
-- For more info, see [@Target::has_gpu_feature@](https://halide-lang.org/docs/struct_halide_1_1_target.html#a22bf80aa6dc3a700c9732050d2341a80).
hasGpuFeature :: Target -> Bool
hasGpuFeature :: Target -> Bool
hasGpuFeature Target
target =
  forall a. IO a -> a
unsafePerformIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. Enum a => Int -> a
toEnum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) forall a b. (a -> b) -> a -> b
$
    forall a. Target -> (Ptr CxxTarget -> IO a) -> IO a
withCxxTarget Target
target forall a b. (a -> b) -> a -> b
$ \Ptr CxxTarget
t ->
      [CU.exp| bool { $(Halide::Target* t)->has_gpu_feature() } |]

-- | An enum describing the type of device API.
--
-- This is the Haskell counterpart of [@Halide::DeviceAPI@](https://halide-lang.org/docs/namespace_halide.html#aa26c7f430d2b1c44ba3e1d3f6df2ba6e).
data DeviceAPI
  = DeviceNone
  | DeviceHost
  | DeviceDefaultGPU
  | DeviceCUDA
  | DeviceOpenCL
  | DeviceOpenGLCompute
  | DeviceMetal
  | DeviceHexagon
  | DeviceHexagonDma
  | DeviceD3D12Compute
  deriving stock (Int -> DeviceAPI -> ShowS
[DeviceAPI] -> ShowS
DeviceAPI -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DeviceAPI] -> ShowS
$cshowList :: [DeviceAPI] -> ShowS
show :: DeviceAPI -> String
$cshow :: DeviceAPI -> String
showsPrec :: Int -> DeviceAPI -> ShowS
$cshowsPrec :: Int -> DeviceAPI -> ShowS
Show, DeviceAPI -> DeviceAPI -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DeviceAPI -> DeviceAPI -> Bool
$c/= :: DeviceAPI -> DeviceAPI -> Bool
== :: DeviceAPI -> DeviceAPI -> Bool
$c== :: DeviceAPI -> DeviceAPI -> Bool
Eq, Eq DeviceAPI
DeviceAPI -> DeviceAPI -> Bool
DeviceAPI -> DeviceAPI -> Ordering
DeviceAPI -> DeviceAPI -> DeviceAPI
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 :: DeviceAPI -> DeviceAPI -> DeviceAPI
$cmin :: DeviceAPI -> DeviceAPI -> DeviceAPI
max :: DeviceAPI -> DeviceAPI -> DeviceAPI
$cmax :: DeviceAPI -> DeviceAPI -> DeviceAPI
>= :: DeviceAPI -> DeviceAPI -> Bool
$c>= :: DeviceAPI -> DeviceAPI -> Bool
> :: DeviceAPI -> DeviceAPI -> Bool
$c> :: DeviceAPI -> DeviceAPI -> Bool
<= :: DeviceAPI -> DeviceAPI -> Bool
$c<= :: DeviceAPI -> DeviceAPI -> Bool
< :: DeviceAPI -> DeviceAPI -> Bool
$c< :: DeviceAPI -> DeviceAPI -> Bool
compare :: DeviceAPI -> DeviceAPI -> Ordering
$ccompare :: DeviceAPI -> DeviceAPI -> Ordering
Ord)

instance Enum DeviceAPI where
  fromEnum :: DeviceAPI -> Int
fromEnum =
    forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
      DeviceAPI
DeviceNone -> [CU.pure| int { static_cast<int>(Halide::DeviceAPI::None) } |]
      DeviceAPI
DeviceHost -> [CU.pure| int { static_cast<int>(Halide::DeviceAPI::Host) } |]
      DeviceAPI
DeviceDefaultGPU -> [CU.pure| int { static_cast<int>(Halide::DeviceAPI::Default_GPU) } |]
      DeviceAPI
DeviceCUDA -> [CU.pure| int { static_cast<int>(Halide::DeviceAPI::CUDA) } |]
      DeviceAPI
DeviceOpenCL -> [CU.pure| int { static_cast<int>(Halide::DeviceAPI::OpenCL) } |]
      DeviceAPI
DeviceOpenGLCompute -> [CU.pure| int { static_cast<int>(Halide::DeviceAPI::OpenGLCompute) } |]
      DeviceAPI
DeviceMetal -> [CU.pure| int { static_cast<int>(Halide::DeviceAPI::Metal) } |]
      DeviceAPI
DeviceHexagon -> [CU.pure| int { static_cast<int>(Halide::DeviceAPI::Hexagon) } |]
      DeviceAPI
DeviceHexagonDma -> [CU.pure| int { static_cast<int>(Halide::DeviceAPI::HexagonDma) } |]
      DeviceAPI
DeviceD3D12Compute -> [CU.pure| int { static_cast<int>(Halide::DeviceAPI::D3D12Compute) } |]
  toEnum :: Int -> DeviceAPI
toEnum Int
k
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { static_cast<int>(Halide::DeviceAPI::None) } |] = DeviceAPI
DeviceNone
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { static_cast<int>(Halide::DeviceAPI::Host) } |] = DeviceAPI
DeviceHost
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { static_cast<int>(Halide::DeviceAPI::Default_GPU) } |] = DeviceAPI
DeviceDefaultGPU
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { static_cast<int>(Halide::DeviceAPI::CUDA) } |] = DeviceAPI
DeviceCUDA
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { static_cast<int>(Halide::DeviceAPI::OpenCL) } |] = DeviceAPI
DeviceOpenCL
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { static_cast<int>(Halide::DeviceAPI::OpenGLCompute) } |] = DeviceAPI
DeviceOpenGLCompute
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { static_cast<int>(Halide::DeviceAPI::Metal) } |] = DeviceAPI
DeviceMetal
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { static_cast<int>(Halide::DeviceAPI::Hexagon) } |] = DeviceAPI
DeviceHexagon
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { static_cast<int>(Halide::DeviceAPI::HexagonDma) } |] = DeviceAPI
DeviceHexagonDma
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { static_cast<int>(Halide::DeviceAPI::D3D12Compute) } |] = DeviceAPI
DeviceD3D12Compute
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { static_cast<int>(Halide::DeviceAPI::D3D12Compute) } |] = DeviceAPI
DeviceD3D12Compute
    | Bool
otherwise = forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"invalid DeviceAPI: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Int
k

wrapCxxTarget :: Ptr CxxTarget -> IO Target
wrapCxxTarget :: Ptr CxxTarget -> IO Target
wrapCxxTarget = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ForeignPtr CxxTarget -> Target
Target forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FunPtr (Ptr CxxTarget -> IO ())
deleter
  where
    deleter :: FunPtr (Ptr CxxTarget -> IO ())
deleter = [C.funPtr| void deleteTarget(Halide::Target* p) { delete p; } |]

-- | Convert 'Target' into @Halide::Target*@ and use it in an 'IO' action.
withCxxTarget :: Target -> (Ptr CxxTarget -> IO a) -> IO a
withCxxTarget :: forall a. Target -> (Ptr CxxTarget -> IO a) -> IO a
withCxxTarget (Target ForeignPtr CxxTarget
fp) = forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr CxxTarget
fp

deviceAPIForTarget :: Target -> DeviceAPI
deviceAPIForTarget :: Target -> DeviceAPI
deviceAPIForTarget Target
target = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$
  forall a. Target -> (Ptr CxxTarget -> IO a) -> IO a
withCxxTarget Target
target forall a b. (a -> b) -> a -> b
$ \Ptr CxxTarget
target' ->
    forall a. Enum a => Int -> a
toEnum forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [CU.exp| int { static_cast<int>(Halide::get_default_device_api_for_target(
            *$(Halide::Target* target'))) } |]

-- targetFeatureForDeviceAPI :: DeviceAPI -> Maybe TargetFeature
-- targetFeatureForDeviceAPI deviceAPI =
--   toFeature . unsafePerformIO $
--     [CU.block| int {
--       auto feature = Halide::target_feature_for_device_api(
--                        static_cast<Halide::DeviceAPI>($(int api)));
--       return (feature == Halide::Target::FeatureEnd) ? (-1) : static_cast<int>(feature);
--     } |]
--   where
--     api = fromIntegral . fromEnum $ deviceAPI
--     toFeature n
--       | n > 0 = Just . toEnum . fromIntegral $ n
--       | otherwise = Nothing

-- | A test that tries to compile and run a Halide pipeline using 'FeatureCUDA'.
--
-- This is implemented fully in C++ to make sure that we test the installation
-- rather than our Haskell code.
--
-- On non-NixOS systems one should do the following:
--
-- > nixGLNvidia cabal repl --ghc-options='-fobject-code -O0'
-- > ghci> testCUDA
testCUDA :: IO ()
testCUDA :: IO ()
testCUDA = do
  [C.throwBlock| void {
    handle_halide_exceptions([](){
      // Define a gradient function.
      Halide::Func f;
      Halide::Var x, y, xo, xi, yo, yi;
      f(x, y) = x + y;
      // Schedule f on the GPU in 16x16 tiles.
      f.gpu_tile(x, y, xo, yo, xi, yi, 16, 16);
      // Construct a target that uses the GPU.
      Halide::Target target = Halide::get_host_target();
      // Set CUDA as the GPU backend.
      target.set_feature(Halide::Target::CUDA);
      // Enable debugging so that you can see what CUDA API calls we do.
      target.set_feature(Halide::Target::Debug);
      // JIT-compile the pipeline.
      f.compile_jit(target);
      // Run it.
      Halide::Buffer<int> result = f.realize({32, 32});
      // Check correctness
      for (int y = 0; y < result.height(); y++) {
          for (int x = 0; x < result.width(); x++) {
              if (result(x, y) != x + y) {
                  printf("result(%d, %d) = %d instead of %d\n",
                         x, y, result(x, y), x + y);
              }
          }
      }
    });
  } |]

-- | Similar to 'testCUDA' but for 'FeatureOpenCL'.
testOpenCL :: IO ()
testOpenCL :: IO ()
testOpenCL = do
  [C.throwBlock| void {
    handle_halide_exceptions([](){
      Halide::Func f;
      Halide::Var x, y, xo, xi, yo, yi;
      f(x, y) = x + y;
      f.gpu_tile(x, y, xo, yo, xi, yi, 4, 4);
      Halide::Target target = Halide::get_host_target();
      target.set_feature(Halide::Target::OpenCL);
      target.set_feature(Halide::Target::Debug);
      fprintf(stderr, "Compiling ...\n");
      f.compile_jit(target);
      fprintf(stderr, "Running on OpenCL ...\n");
      Halide::Buffer<int> result = f.realize({32, 32});
      for (int y = 0; y < result.height(); y++) {
          for (int x = 0; x < result.width(); x++) {
              if (result(x, y) != x + y) {
                  printf("result(%d, %d) = %d instead of %d\n",
                         x, y, result(x, y), x + y);
              }
          }
      }
    });
  } |]

-- |
--
-- Note: generated automatically using
--
-- > cat $HALIDE_PATH/include/Halide.h | \
-- >   grep -E '.* = halide_target_feature_.*' | \
-- >   sed -E 's/^\s*(.*) = .*$/  | \1/g' | \
-- >   grep -v FeatureEnd
data TargetFeature
  = FeatureJIT
  | FeatureDebug
  | FeatureNoAsserts
  | FeatureNoBoundsQuery
  | FeatureSSE41
  | FeatureAVX
  | FeatureAVX2
  | FeatureFMA
  | FeatureFMA4
  | FeatureF16C
  | FeatureARMv7s
  | FeatureNoNEON
  | FeatureVSX
  | FeaturePOWER_ARCH_2_07
  | FeatureCUDA
  | FeatureCUDACapability30
  | FeatureCUDACapability32
  | FeatureCUDACapability35
  | FeatureCUDACapability50
  | FeatureCUDACapability61
  | FeatureCUDACapability70
  | FeatureCUDACapability75
  | FeatureCUDACapability80
  | FeatureCUDACapability86
  | FeatureOpenCL
  | FeatureCLDoubles
  | FeatureCLHalf
  | FeatureCLAtomics64
  | FeatureOpenGLCompute
  | FeatureEGL
  | FeatureUserContext
  | FeatureProfile
  | FeatureNoRuntime
  | FeatureMetal
  | FeatureCPlusPlusMangling
  | FeatureLargeBuffers
  | FeatureHexagonDma
  | FeatureHVX_128
  | FeatureHVX_v62
  | FeatureHVX_v65
  | FeatureHVX_v66
  | -- Removed in upstream Halide FeatureHVX_shared_object
    FeatureFuzzFloatStores
  | FeatureSoftFloatABI
  | FeatureMSAN
  | FeatureAVX512
  | FeatureAVX512_KNL
  | FeatureAVX512_Skylake
  | FeatureAVX512_Cannonlake
  | FeatureAVX512_SapphireRapids
  | FeatureTraceLoads
  | FeatureTraceStores
  | FeatureTraceRealizations
  | FeatureTracePipeline
  | FeatureD3D12Compute
  | FeatureStrictFloat
  | FeatureTSAN
  | FeatureASAN
  | FeatureCheckUnsafePromises
  | FeatureEmbedBitcode
  | FeatureEnableLLVMLoopOpt
  | FeatureWasmSimd128
  | FeatureWasmSignExt
  | FeatureWasmSatFloatToInt
  | FeatureWasmThreads
  | FeatureWasmBulkMemory
  | FeatureSVE
  | FeatureSVE2
  | FeatureARMDotProd
  | FeatureARMFp16
  | FeatureRVV
  | FeatureARMv81a
  | FeatureSanitizerCoverage
  | FeatureProfileByTimer
  | FeatureSPIRV
  -- removed in v15.0.0
  -- \| FeatureSemihosting
  deriving stock (TargetFeature -> TargetFeature -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TargetFeature -> TargetFeature -> Bool
$c/= :: TargetFeature -> TargetFeature -> Bool
== :: TargetFeature -> TargetFeature -> Bool
$c== :: TargetFeature -> TargetFeature -> Bool
Eq, Int -> TargetFeature -> ShowS
[TargetFeature] -> ShowS
TargetFeature -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TargetFeature] -> ShowS
$cshowList :: [TargetFeature] -> ShowS
show :: TargetFeature -> String
$cshow :: TargetFeature -> String
showsPrec :: Int -> TargetFeature -> ShowS
$cshowsPrec :: Int -> TargetFeature -> ShowS
Show, Eq TargetFeature
TargetFeature -> TargetFeature -> Bool
TargetFeature -> TargetFeature -> Ordering
TargetFeature -> TargetFeature -> TargetFeature
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 :: TargetFeature -> TargetFeature -> TargetFeature
$cmin :: TargetFeature -> TargetFeature -> TargetFeature
max :: TargetFeature -> TargetFeature -> TargetFeature
$cmax :: TargetFeature -> TargetFeature -> TargetFeature
>= :: TargetFeature -> TargetFeature -> Bool
$c>= :: TargetFeature -> TargetFeature -> Bool
> :: TargetFeature -> TargetFeature -> Bool
$c> :: TargetFeature -> TargetFeature -> Bool
<= :: TargetFeature -> TargetFeature -> Bool
$c<= :: TargetFeature -> TargetFeature -> Bool
< :: TargetFeature -> TargetFeature -> Bool
$c< :: TargetFeature -> TargetFeature -> Bool
compare :: TargetFeature -> TargetFeature -> Ordering
$ccompare :: TargetFeature -> TargetFeature -> Ordering
Ord)

instance Enum TargetFeature where
  -- Generated using
  -- cat $HALIDE_PATH/include/Halide.h | grep -E '.* = halide_target_feature_.*' | grep -v 'FeatureEnd' | sed -E 's/[ \t]+(.*) = ([^,]*).*/    Feature\1 -> [CU.pure| int { \2 } |]/'
  fromEnum :: TargetFeature -> Int
fromEnum =
    forall a b. (Integral a, Num b) => a -> b
fromIntegral forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
      TargetFeature
FeatureJIT -> [CU.pure| int { halide_target_feature_jit } |]
      TargetFeature
FeatureDebug -> [CU.pure| int { halide_target_feature_debug } |]
      TargetFeature
FeatureNoAsserts -> [CU.pure| int { halide_target_feature_no_asserts } |]
      TargetFeature
FeatureNoBoundsQuery -> [CU.pure| int { halide_target_feature_no_bounds_query } |]
      TargetFeature
FeatureSSE41 -> [CU.pure| int { halide_target_feature_sse41 } |]
      TargetFeature
FeatureAVX -> [CU.pure| int { halide_target_feature_avx } |]
      TargetFeature
FeatureAVX2 -> [CU.pure| int { halide_target_feature_avx2 } |]
      TargetFeature
FeatureFMA -> [CU.pure| int { halide_target_feature_fma } |]
      TargetFeature
FeatureFMA4 -> [CU.pure| int { halide_target_feature_fma4 } |]
      TargetFeature
FeatureF16C -> [CU.pure| int { halide_target_feature_f16c } |]
      TargetFeature
FeatureARMv7s -> [CU.pure| int { halide_target_feature_armv7s } |]
      TargetFeature
FeatureNoNEON -> [CU.pure| int { halide_target_feature_no_neon } |]
      TargetFeature
FeatureVSX -> [CU.pure| int { halide_target_feature_vsx } |]
      TargetFeature
FeaturePOWER_ARCH_2_07 -> [CU.pure| int { halide_target_feature_power_arch_2_07 } |]
      TargetFeature
FeatureCUDA -> [CU.pure| int { halide_target_feature_cuda } |]
      TargetFeature
FeatureCUDACapability30 -> [CU.pure| int { halide_target_feature_cuda_capability30 } |]
      TargetFeature
FeatureCUDACapability32 -> [CU.pure| int { halide_target_feature_cuda_capability32 } |]
      TargetFeature
FeatureCUDACapability35 -> [CU.pure| int { halide_target_feature_cuda_capability35 } |]
      TargetFeature
FeatureCUDACapability50 -> [CU.pure| int { halide_target_feature_cuda_capability50 } |]
      TargetFeature
FeatureCUDACapability61 -> [CU.pure| int { halide_target_feature_cuda_capability61 } |]
      TargetFeature
FeatureCUDACapability70 -> [CU.pure| int { halide_target_feature_cuda_capability70 } |]
      TargetFeature
FeatureCUDACapability75 -> [CU.pure| int { halide_target_feature_cuda_capability75 } |]
      TargetFeature
FeatureCUDACapability80 -> [CU.pure| int { halide_target_feature_cuda_capability80 } |]
      TargetFeature
FeatureCUDACapability86 -> [CU.pure| int { halide_target_feature_cuda_capability86 } |]
      TargetFeature
FeatureOpenCL -> [CU.pure| int { halide_target_feature_opencl } |]
      TargetFeature
FeatureCLDoubles -> [CU.pure| int { halide_target_feature_cl_doubles } |]
      TargetFeature
FeatureCLHalf -> [CU.pure| int { halide_target_feature_cl_half } |]
      TargetFeature
FeatureCLAtomics64 -> [CU.pure| int { halide_target_feature_cl_atomic64 } |]
      TargetFeature
FeatureOpenGLCompute -> [CU.pure| int { halide_target_feature_openglcompute } |]
      TargetFeature
FeatureEGL -> [CU.pure| int { halide_target_feature_egl } |]
      TargetFeature
FeatureUserContext -> [CU.pure| int { halide_target_feature_user_context } |]
      TargetFeature
FeatureProfile -> [CU.pure| int { halide_target_feature_profile } |]
      TargetFeature
FeatureNoRuntime -> [CU.pure| int { halide_target_feature_no_runtime } |]
      TargetFeature
FeatureMetal -> [CU.pure| int { halide_target_feature_metal } |]
      TargetFeature
FeatureCPlusPlusMangling -> [CU.pure| int { halide_target_feature_c_plus_plus_mangling } |]
      TargetFeature
FeatureLargeBuffers -> [CU.pure| int { halide_target_feature_large_buffers } |]
      TargetFeature
FeatureHexagonDma -> [CU.pure| int { halide_target_feature_hexagon_dma } |]
      TargetFeature
FeatureHVX_128 -> [CU.pure| int { halide_target_feature_hvx_128 } |]
      TargetFeature
FeatureHVX_v62 -> [CU.pure| int { halide_target_feature_hvx_v62 } |]
      TargetFeature
FeatureHVX_v65 -> [CU.pure| int { halide_target_feature_hvx_v65 } |]
      TargetFeature
FeatureHVX_v66 -> [CU.pure| int { halide_target_feature_hvx_v66 } |]
      -- FeatureHVX_shared_object -> [CU.pure| int { halide_target_feature_hvx_use_shared_object } |]
      TargetFeature
FeatureFuzzFloatStores -> [CU.pure| int { halide_target_feature_fuzz_float_stores } |]
      TargetFeature
FeatureSoftFloatABI -> [CU.pure| int { halide_target_feature_soft_float_abi } |]
      TargetFeature
FeatureMSAN -> [CU.pure| int { halide_target_feature_msan } |]
      TargetFeature
FeatureAVX512 -> [CU.pure| int { halide_target_feature_avx512 } |]
      TargetFeature
FeatureAVX512_KNL -> [CU.pure| int { halide_target_feature_avx512_knl } |]
      TargetFeature
FeatureAVX512_Skylake -> [CU.pure| int { halide_target_feature_avx512_skylake } |]
      TargetFeature
FeatureAVX512_Cannonlake -> [CU.pure| int { halide_target_feature_avx512_cannonlake } |]
      TargetFeature
FeatureAVX512_SapphireRapids -> [CU.pure| int { halide_target_feature_avx512_sapphirerapids } |]
      TargetFeature
FeatureTraceLoads -> [CU.pure| int { halide_target_feature_trace_loads } |]
      TargetFeature
FeatureTraceStores -> [CU.pure| int { halide_target_feature_trace_stores } |]
      TargetFeature
FeatureTraceRealizations -> [CU.pure| int { halide_target_feature_trace_realizations } |]
      TargetFeature
FeatureTracePipeline -> [CU.pure| int { halide_target_feature_trace_pipeline } |]
      TargetFeature
FeatureD3D12Compute -> [CU.pure| int { halide_target_feature_d3d12compute } |]
      TargetFeature
FeatureStrictFloat -> [CU.pure| int { halide_target_feature_strict_float } |]
      TargetFeature
FeatureTSAN -> [CU.pure| int { halide_target_feature_tsan } |]
      TargetFeature
FeatureASAN -> [CU.pure| int { halide_target_feature_asan } |]
      TargetFeature
FeatureCheckUnsafePromises -> [CU.pure| int { halide_target_feature_check_unsafe_promises } |]
      TargetFeature
FeatureEmbedBitcode -> [CU.pure| int { halide_target_feature_embed_bitcode } |]
      TargetFeature
FeatureEnableLLVMLoopOpt -> [CU.pure| int { halide_target_feature_enable_llvm_loop_opt } |]
      TargetFeature
FeatureWasmSimd128 -> [CU.pure| int { halide_target_feature_wasm_simd128 } |]
      TargetFeature
FeatureWasmSignExt -> [CU.pure| int { halide_target_feature_wasm_signext } |]
      TargetFeature
FeatureWasmSatFloatToInt -> [CU.pure| int { halide_target_feature_wasm_sat_float_to_int } |]
      TargetFeature
FeatureWasmThreads -> [CU.pure| int { halide_target_feature_wasm_threads } |]
      TargetFeature
FeatureWasmBulkMemory -> [CU.pure| int { halide_target_feature_wasm_bulk_memory } |]
      TargetFeature
FeatureSVE -> [CU.pure| int { halide_target_feature_sve } |]
      TargetFeature
FeatureSVE2 -> [CU.pure| int { halide_target_feature_sve2 } |]
      TargetFeature
FeatureARMDotProd -> [CU.pure| int { halide_target_feature_arm_dot_prod } |]
      TargetFeature
FeatureARMFp16 -> [CU.pure| int { halide_target_feature_arm_fp16 } |]
      TargetFeature
FeatureRVV -> [CU.pure| int { halide_target_feature_rvv } |]
      TargetFeature
FeatureARMv81a -> [CU.pure| int { halide_target_feature_armv81a } |]
      TargetFeature
FeatureSanitizerCoverage -> [CU.pure| int { halide_target_feature_sanitizer_coverage } |]
      TargetFeature
FeatureProfileByTimer -> [CU.pure| int { halide_target_feature_profile_by_timer } |]
      TargetFeature
FeatureSPIRV -> [CU.pure| int { halide_target_feature_spirv } |]

  -- FeatureSemihosting -> [CU.pure| int { halide_target_feature_semihosting } |]
  toEnum :: Int -> TargetFeature
toEnum Int
k
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_jit } |] = TargetFeature
FeatureJIT
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_debug } |] = TargetFeature
FeatureDebug
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_no_asserts } |] = TargetFeature
FeatureNoAsserts
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_no_bounds_query } |] = TargetFeature
FeatureNoBoundsQuery
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_sse41 } |] = TargetFeature
FeatureSSE41
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_avx } |] = TargetFeature
FeatureAVX
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_avx2 } |] = TargetFeature
FeatureAVX2
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_fma } |] = TargetFeature
FeatureFMA
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_fma4 } |] = TargetFeature
FeatureFMA4
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_f16c } |] = TargetFeature
FeatureF16C
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_armv7s } |] = TargetFeature
FeatureARMv7s
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_no_neon } |] = TargetFeature
FeatureNoNEON
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_vsx } |] = TargetFeature
FeatureVSX
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_power_arch_2_07 } |] = TargetFeature
FeaturePOWER_ARCH_2_07
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_cuda } |] = TargetFeature
FeatureCUDA
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_cuda_capability30 } |] = TargetFeature
FeatureCUDACapability30
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_cuda_capability32 } |] = TargetFeature
FeatureCUDACapability32
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_cuda_capability35 } |] = TargetFeature
FeatureCUDACapability35
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_cuda_capability50 } |] = TargetFeature
FeatureCUDACapability50
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_cuda_capability61 } |] = TargetFeature
FeatureCUDACapability61
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_cuda_capability70 } |] = TargetFeature
FeatureCUDACapability70
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_cuda_capability75 } |] = TargetFeature
FeatureCUDACapability75
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_cuda_capability80 } |] = TargetFeature
FeatureCUDACapability80
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_cuda_capability86 } |] = TargetFeature
FeatureCUDACapability86
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_opencl } |] = TargetFeature
FeatureOpenCL
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_cl_doubles } |] = TargetFeature
FeatureCLDoubles
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_cl_half } |] = TargetFeature
FeatureCLHalf
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_cl_atomic64 } |] = TargetFeature
FeatureCLAtomics64
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_openglcompute } |] = TargetFeature
FeatureOpenGLCompute
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_egl } |] = TargetFeature
FeatureEGL
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_user_context } |] = TargetFeature
FeatureUserContext
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_profile } |] = TargetFeature
FeatureProfile
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_no_runtime } |] = TargetFeature
FeatureNoRuntime
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_metal } |] = TargetFeature
FeatureMetal
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_c_plus_plus_mangling } |] = TargetFeature
FeatureCPlusPlusMangling
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_large_buffers } |] = TargetFeature
FeatureLargeBuffers
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_hexagon_dma } |] = TargetFeature
FeatureHexagonDma
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_hvx_128 } |] = TargetFeature
FeatureHVX_128
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_hvx_v62 } |] = TargetFeature
FeatureHVX_v62
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_hvx_v65 } |] = TargetFeature
FeatureHVX_v65
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_hvx_v66 } |] = TargetFeature
FeatureHVX_v66
    -- \| fromIntegral k == [CU.pure| int { halide_target_feature_hvx_use_shared_object } |] = FeatureHVX_shared_object
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_fuzz_float_stores } |] = TargetFeature
FeatureFuzzFloatStores
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_soft_float_abi } |] = TargetFeature
FeatureSoftFloatABI
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_msan } |] = TargetFeature
FeatureMSAN
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_avx512 } |] = TargetFeature
FeatureAVX512
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_avx512_knl } |] = TargetFeature
FeatureAVX512_KNL
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_avx512_skylake } |] = TargetFeature
FeatureAVX512_Skylake
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_avx512_cannonlake } |] = TargetFeature
FeatureAVX512_Cannonlake
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_avx512_sapphirerapids } |] = TargetFeature
FeatureAVX512_SapphireRapids
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_trace_loads } |] = TargetFeature
FeatureTraceLoads
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_trace_stores } |] = TargetFeature
FeatureTraceStores
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_trace_realizations } |] = TargetFeature
FeatureTraceRealizations
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_trace_pipeline } |] = TargetFeature
FeatureTracePipeline
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_d3d12compute } |] = TargetFeature
FeatureD3D12Compute
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_strict_float } |] = TargetFeature
FeatureStrictFloat
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_tsan } |] = TargetFeature
FeatureTSAN
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_asan } |] = TargetFeature
FeatureASAN
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_check_unsafe_promises } |] = TargetFeature
FeatureCheckUnsafePromises
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_embed_bitcode } |] = TargetFeature
FeatureEmbedBitcode
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_enable_llvm_loop_opt } |] = TargetFeature
FeatureEnableLLVMLoopOpt
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_wasm_simd128 } |] = TargetFeature
FeatureWasmSimd128
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_wasm_signext } |] = TargetFeature
FeatureWasmSignExt
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_wasm_sat_float_to_int } |] = TargetFeature
FeatureWasmSatFloatToInt
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_wasm_threads } |] = TargetFeature
FeatureWasmThreads
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_wasm_bulk_memory } |] = TargetFeature
FeatureWasmBulkMemory
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_sve } |] = TargetFeature
FeatureSVE
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_sve2 } |] = TargetFeature
FeatureSVE2
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_arm_dot_prod } |] = TargetFeature
FeatureARMDotProd
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_arm_fp16 } |] = TargetFeature
FeatureARMFp16
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_rvv } |] = TargetFeature
FeatureRVV
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_armv81a } |] = TargetFeature
FeatureARMv81a
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_sanitizer_coverage } |] = TargetFeature
FeatureSanitizerCoverage
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_profile_by_timer } |] = TargetFeature
FeatureProfileByTimer
    | forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
k forall a. Eq a => a -> a -> Bool
== [CU.pure| int { halide_target_feature_spirv } |] = TargetFeature
FeatureSPIRV
    -- \| fromIntegral k == [CU.pure| int { halide_target_feature_semihosting } |] = FeatureSemihosting
    | Bool
otherwise = forall a. HasCallStack => String -> a
error forall a b. (a -> b) -> a -> b
$ String
"unknown Target feature: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show Int
k