| Copyright | (c) Tom Westerhout 2023 |
|---|---|
| Safe Haskell | Safe-Inferred |
| Language | GHC2021 |
Language.Halide
Description
This package provides Haskell bindings that allow to write Halide embedded in Haskell without C++.
This module contains the reference documentation for Halide. If you're new, the best way to learn Halide is to have a look at the tutorials.
Synopsis
- data Expr a
- = Expr (ForeignPtr CxxExpr)
- | Var (ForeignPtr CxxVar)
- | RVar (ForeignPtr CxxRVar)
- | ScalarParam (IORef (Maybe (ForeignPtr CxxParameter)))
- type Var = Expr Int32
- type RVar = Expr Int32
- type VarOrRVar = Expr Int32
- class Storable a => IsHalideType a
- mkExpr :: IsHalideType a => a -> Expr a
- mkVar :: Text -> IO (Expr Int32)
- mkRVar :: Text -> Expr Int32 -> Expr Int32 -> IO (Expr Int32)
- undef :: forall a. IsHalideType a => Expr a
- cast :: forall to from. (IsHalideType to, IsHalideType from) => Expr from -> Expr to
- bool :: IsHalideType a => Expr Bool -> Expr a -> Expr a -> Expr a
- toIntImm :: IsHalideType a => Expr a -> Maybe Int
- printed :: IsHalideType a => Expr a -> Expr a
- evaluate :: forall a. IsHalideType a => Expr a -> IO a
- eq :: IsHalideType a => Expr a -> Expr a -> Expr Bool
- neq :: IsHalideType a => Expr a -> Expr a -> Expr Bool
- lt :: IsHalideType a => Expr a -> Expr a -> Expr Bool
- lte :: IsHalideType a => Expr a -> Expr a -> Expr Bool
- gt :: IsHalideType a => Expr a -> Expr a -> Expr Bool
- gte :: IsHalideType a => Expr a -> Expr a -> Expr Bool
- data Func (t :: FuncTy) (n :: Nat) (a :: Type) where
- Func :: !(ForeignPtr CxxFunc) -> Func 'FuncTy n a
- Param :: !(IORef (Maybe (ForeignPtr CxxImageParam))) -> Func 'ParamTy n a
- data FuncTy
- newtype Stage (n :: Nat) (a :: Type) = Stage (ForeignPtr CxxStage)
- define :: (IsTuple (Arguments ts) i, All ((~) Var) ts, Length ts ~ n, KnownNat n, IsHalideType a) => Text -> i -> Expr a -> IO (Func 'FuncTy n a)
- update :: (IsTuple (Arguments ts) i, All ((~) (Expr Int32)) ts, Length ts ~ n, KnownNat n, IsHalideType a) => Func 'FuncTy n a -> i -> Expr a -> IO ()
- (!) :: (IsTuple (Arguments ts) i, All ((~) (Expr Int32)) ts, Length ts ~ n, KnownNat n, IsHalideType a) => Func t n a -> i -> Expr a
- getArgs :: (KnownNat n, IsHalideType a) => Func t n a -> IO [Var]
- hasUpdateDefinitions :: (KnownNat n, IsHalideType a) => Func t n a -> IO Bool
- getUpdateStage :: (KnownNat n, IsHalideType a) => Int -> Func 'FuncTy n a -> IO (Stage n a)
- newtype HalideBuffer (n :: Nat) (a :: Type) = HalideBuffer {}
- allocaCpuBuffer :: forall n a b. (HasCallStack, KnownNat n, IsHalideType a) => [Int] -> (Ptr (HalideBuffer n a) -> IO b) -> IO b
- class IsListPeek a where
- type ListPeekElem a :: Type
- peekToList :: HasCallStack => Ptr a -> IO [ListPeekElem a]
- class (KnownNat n, IsHalideType a) => IsHalideBuffer t n a where
- withHalideBufferImpl :: t -> (Ptr (HalideBuffer n a) -> IO b) -> IO b
- withHalideBuffer :: forall n a t b. IsHalideBuffer t n a => t -> (Ptr (HalideBuffer n a) -> IO b) -> IO b
- bufferFromPtrShapeStrides :: forall n a b. (HasCallStack, KnownNat n, IsHalideType a) => Ptr a -> [Int] -> [Int] -> (Ptr (HalideBuffer n a) -> IO b) -> IO b
- bufferFromPtrShape :: (HasCallStack, KnownNat n, IsHalideType a) => Ptr a -> [Int] -> (Ptr (HalideBuffer n a) -> IO b) -> IO b
- realize :: forall n a t b. (KnownNat n, IsHalideType a) => Func t n a -> [Int] -> (Ptr (HalideBuffer n a) -> IO b) -> IO b
- asBufferParam :: forall n a t b. IsHalideBuffer t n a => t -> (Func 'ParamTy n a -> IO b) -> IO b
- compile :: forall n a t f kernel. (IsFuncBuilder f t n a, Curry (Lowered (FunctionArguments f)) (Ptr (HalideBuffer n a) -> IO ()) kernel) => f -> IO kernel
- buffer :: forall n a. (KnownNat n, IsHalideType a) => Text -> Func 'ParamTy n a -> Func 'ParamTy n a
- scalar :: forall a. IsHalideType a => Text -> Expr a -> Expr a
- newtype Dimension = Dimension (ForeignPtr CxxDimension)
- dim :: forall n a. (HasCallStack, KnownNat n, IsHalideType a) => Int -> Func 'ParamTy n a -> IO Dimension
- setMin :: Expr Int32 -> Dimension -> IO Dimension
- setExtent :: Expr Int32 -> Dimension -> IO Dimension
- setStride :: Expr Int32 -> Dimension -> IO Dimension
- setEstimate :: Expr Int32 -> Expr Int32 -> Dimension -> IO Dimension
- newtype Target = Target (ForeignPtr CxxTarget)
- hostTarget :: Target
- gpuTarget :: Maybe Target
- compileForTarget :: forall n a t f kernel. (IsFuncBuilder f t n a, Curry (Lowered (FunctionArguments f)) (Ptr (HalideBuffer n a) -> IO ()) kernel) => Target -> f -> IO kernel
- data DeviceAPI
- 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
- | 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
- | FeatureSemihosting
- setFeature :: TargetFeature -> Target -> Target
- hasGpuFeature :: Target -> Bool
- hostSupportsTargetDevice :: Target -> Bool
- class (KnownNat n, IsHalideType a) => Schedulable f n a where
- vectorize :: VarOrRVar -> f n a -> IO (f n a)
- unroll :: VarOrRVar -> f n a -> IO (f n a)
- reorder :: [VarOrRVar] -> f n a -> IO (f n a)
- split :: TailStrategy -> VarOrRVar -> (VarOrRVar, VarOrRVar) -> Expr Int32 -> f n a -> IO (f n a)
- fuse :: (VarOrRVar, VarOrRVar) -> VarOrRVar -> f n a -> IO (f n a)
- serial :: VarOrRVar -> f n a -> IO (f n a)
- parallel :: VarOrRVar -> f n a -> IO (f n a)
- specialize :: Expr Bool -> f n a -> IO (Stage n a)
- specializeFail :: Text -> f n a -> IO ()
- gpuBlocks :: (IndexTuple i ts, 1 <= Length ts, Length ts <= 3) => DeviceAPI -> i -> f n a -> IO (f n a)
- gpuThreads :: (IndexTuple i ts, 1 <= Length ts, Length ts <= 3) => DeviceAPI -> i -> f n a -> IO (f n a)
- gpuLanes :: DeviceAPI -> VarOrRVar -> f n a -> IO (f n a)
- computeWith :: LoopAlignStrategy -> f n a -> LoopLevel t -> IO ()
- data TailStrategy
- data LoopLevel (t :: LoopLevelTy) where
- data LoopLevelTy
- data LoopAlignStrategy
- computeRoot :: (KnownNat n, IsHalideType a) => Func t n a -> IO (Func t n a)
- getStage :: (KnownNat n, IsHalideType a) => Func t n a -> IO (Stage n a)
- getLoopLevel :: (KnownNat n, IsHalideType a) => Func t n a -> Expr Int32 -> IO (LoopLevel 'LockedTy)
- getLoopLevelAtStage :: (KnownNat n, IsHalideType a) => Func t n a -> Expr Int32 -> Int -> IO (LoopLevel 'LockedTy)
- asUsed :: (KnownNat n, IsHalideType a) => Func t n a -> IO (Func 'FuncTy n a)
- asUsedBy :: (KnownNat n, KnownNat m, IsHalideType a, IsHalideType b) => Func t1 n a -> Func 'FuncTy m b -> IO (Func 'FuncTy n a)
- copyToDevice :: (KnownNat n, IsHalideType a) => DeviceAPI -> Func t n a -> IO (Func t n a)
- copyToHost :: (KnownNat n, IsHalideType a) => Func t n a -> IO (Func t n a)
- storeAt :: (KnownNat n, IsHalideType a) => Func 'FuncTy n a -> LoopLevel t -> IO (Func 'FuncTy n a)
- computeAt :: (KnownNat n, IsHalideType a) => Func 'FuncTy n a -> LoopLevel t -> IO (Func 'FuncTy n a)
- estimate :: (KnownNat n, IsHalideType a) => Expr Int32 -> Expr Int32 -> Expr Int32 -> Func t n a -> IO ()
- bound :: (KnownNat n, IsHalideType a) => Expr Int32 -> Expr Int32 -> Expr Int32 -> Func t n a -> IO ()
- prettyLoopNest :: (KnownNat n, IsHalideType r) => Func t n r -> IO Text
- compileToLoweredStmt :: forall n a t f. IsFuncBuilder f t n a => StmtOutputFormat -> Target -> f -> IO Text
- data StmtOutputFormat
- data TraceEvent = TraceEvent {}
- data TraceEventCode
- data TraceLoadStoreContents = TraceLoadStoreContents {
- valuePtr :: !(Ptr ())
- valueType :: !HalideType
- coordinates :: ![Int]
- setCustomTrace :: (KnownNat n, IsHalideType a) => (TraceEvent -> IO ()) -> Func t n a -> IO b -> IO b
- traceStores :: (KnownNat n, IsHalideType a) => Func t n a -> IO (Func t n a)
- traceLoads :: (KnownNat n, IsHalideType a) => Func t n a -> IO (Func t n a)
- collectIterationOrder :: (KnownNat n, IsHalideType a) => (TraceEventCode -> Bool) -> Func t n a -> IO b -> IO ([[Int]], b)
- class (ToTuple a ~ t, FromTuple t ~ a) => IsTuple a t | a -> t, t -> a where
- type family ToTuple t where ...
- type family FromTuple t
- type IndexTuple i ts = (IsTuple (Arguments ts) i, All ((~) (Expr Int32)) ts)
- type family Length (xs :: [k]) :: Nat where ...
- type family All (c :: Type -> Constraint) (ts :: [Type]) :: Constraint where ...
- compileToCallable :: forall n a t f inputs output. (IsFuncBuilder f t n a, Lowered (FunctionArguments f) ~ inputs, Ptr (HalideBuffer n a) ~ output) => Target -> f -> IO (Callable inputs output)
- testCUDA :: IO ()
- testOpenCL :: IO ()
- data SomeLoopLevel where
- SomeLoopLevel :: LoopLevel t -> SomeLoopLevel
- data RawHalideBuffer = RawHalideBuffer {
- halideBufferDevice :: !Word64
- halideBufferDeviceInterface :: !(Ptr HalideDeviceInterface)
- halideBufferHost :: !(Ptr Word8)
- halideBufferFlags :: !Word64
- halideBufferType :: !HalideType
- halideBufferDimensions :: !Int32
- halideBufferDim :: !(Ptr HalideDimension)
- halideBufferPadding :: !(Ptr ())
- data HalideDimension = HalideDimension {}
- data HalideDeviceInterface
- rowMajorStrides :: Integral a => [a] -> [a]
- colMajorStrides :: Integral a => [a] -> [a]
- isDeviceDirty :: Ptr RawHalideBuffer -> IO Bool
- isHostDirty :: Ptr RawHalideBuffer -> IO Bool
- bufferCopyToHost :: Ptr RawHalideBuffer -> IO ()
- data Dim = Dim {}
- data DimType
- data ForType
- data SplitContents = SplitContents {
- splitOld :: !Text
- splitOuter :: !Text
- splitInner :: !Text
- splitFactor :: !(Expr Int32)
- splitExact :: !Bool
- splitTail :: !TailStrategy
- data FuseContents = FuseContents {}
- data Split
- data Bound = Bound {}
- data StorageDim = StorageDim {
- storageVar :: !Text
- storageAlignment :: !(Maybe (Expr Int32))
- storageBound :: !(Maybe (Expr Int32))
- storageFold :: !(Maybe (Expr Int32, Bool))
- data FusedPair = FusedPair !Text !(Text, Int) !(Text, Int)
- data FuseLoopLevel = FuseLoopLevel !SomeLoopLevel
- data StageSchedule = StageSchedule {
- rvars :: ![ReductionVariable]
- splits :: ![Split]
- dims :: ![Dim]
- prefetches :: ![PrefetchDirective]
- fuseLevel :: !FuseLoopLevel
- fusedPairs :: ![FusedPair]
- allowRaceConditions :: !Bool
- atomic :: !Bool
- overrideAtomicAssociativityTest :: !Bool
- data ReductionVariable = ReductionVariable {}
- data PrefetchDirective = PrefetchDirective {
- prefetchFunc :: !Text
- prefetchAt :: !Text
- prefetchFrom :: !Text
- prefetchOffset :: !(Expr Int32)
- prefetchStrategy :: !PrefetchBoundStrategy
- prefetchParameter :: !(Maybe (ForeignPtr CxxParameter))
- getStageSchedule :: (KnownNat n, IsHalideType a) => Stage n a -> IO StageSchedule
- data AutoScheduler
- loadAutoScheduler :: AutoScheduler -> IO ()
- applyAutoScheduler :: (KnownNat n, IsHalideType a) => AutoScheduler -> Target -> Func t n a -> IO Text
- getHalideLibraryPath :: IO (Maybe Text)
- applySplits :: (KnownNat n, IsHalideType a) => [Split] -> Stage n a -> IO ()
- applyDims :: (KnownNat n, IsHalideType a) => [Dim] -> Stage n a -> IO ()
- applySchedule :: (KnownNat n, IsHalideType a) => StageSchedule -> Stage n a -> IO ()
- type IsFuncBuilder f t n a = (All ValidParameter (FunctionArguments f), All ValidArgument (Lowered (FunctionArguments f)), UnCurry f (FunctionArguments f) (FunctionReturn f), PrepareParameters (FunctionArguments f), ReturnsFunc f t n a, KnownNat (Length (FunctionArguments f)), KnownNat (Length (Lowered (FunctionArguments f))))
- class (FunctionReturn f ~ IO (Func t n a), IsHalideType a, KnownNat n) => ReturnsFunc f t n a | f -> t n a
- type family FunctionArguments (f :: Type) :: [Type] where ...
- type family FunctionReturn (f :: Type) :: Type where ...
- class Curry (args :: [Type]) (r :: Type) (f :: Type) | args r -> f where
- curryG :: (Arguments args -> r) -> f
- class UnCurry (f :: Type) (args :: [Type]) (r :: Type) | args r -> f where
- uncurryG :: f -> Arguments args -> r
- type family Lowered (t :: k) :: k where ...
- importHalide :: DecsQ
- data CxxExpr
- data CxxVar
- data CxxRVar
- data CxxParameter
- data CxxFunc
- data CxxImageParam
- data CxxStage
- data CxxDimension
- data CxxTarget
- data CxxLoopLevel
- data Int32
- data Ptr a
- class KnownNat (n :: Nat)
Scalar expressions
The basic building block of Halide pipelines is Expr. Expr a represents a scalar expression of
type a, where a must be an instance of IsHalideType.
A scalar expression in Halide.
To have a nice experience writing arithmetic expressions in terms of Exprs, we want to derive Num,
Floating etc. instances for Expr. Unfortunately, that means that we encode Expr, Var, RVar,
and ScalarParam by the same type, and passing an Expr to a function that expects a Var will produce
a runtime error.
Constructors
| Expr (ForeignPtr CxxExpr) | Scalar expression. |
| Var (ForeignPtr CxxVar) | Index variable. |
| RVar (ForeignPtr CxxRVar) | Reduction variable. |
| ScalarParam (IORef (Maybe (ForeignPtr CxxParameter))) | Scalar parameter. The |
Instances
| HasField "extent" Dimension (Expr Int32) Source # | |
| HasField "max" Dimension (Expr Int32) Source # | |
| HasField "min" Dimension (Expr Int32) Source # | |
| HasField "stride" Dimension (Expr Int32) Source # | |
| HasField "var" (LoopLevel 'LockedTy) (Expr Int32) Source # | |
| (IsHalideType a, Floating a) => Floating (Expr a) Source # | |
| (IsHalideType a, Num a) => Num (Expr a) Source # | |
| (IsHalideType a, Fractional a) => Fractional (Expr a) Source # | |
| IsHalideType a => Show (Expr a) Source # | |
| type FromTuple (Expr a) Source # | |
Defined in Language.Halide.Expr | |
class Storable a => IsHalideType a Source #
Specifies that a type is supported by Halide.
Minimal complete definition
halideTypeFor, toCxxExpr
Instances
| IsHalideType CDouble Source # | |
Defined in Language.Halide.Expr | |
| IsHalideType CFloat Source # | |
Defined in Language.Halide.Expr | |
| IsHalideType Int16 Source # | |
Defined in Language.Halide.Expr | |
| IsHalideType Int32 Source # | |
Defined in Language.Halide.Expr | |
| IsHalideType Int64 Source # | |
Defined in Language.Halide.Expr | |
| IsHalideType Int8 Source # | |
Defined in Language.Halide.Expr | |
| IsHalideType Word16 Source # | |
Defined in Language.Halide.Expr | |
| IsHalideType Word32 Source # | |
Defined in Language.Halide.Expr | |
| IsHalideType Word64 Source # | |
Defined in Language.Halide.Expr | |
| IsHalideType Word8 Source # | |
Defined in Language.Halide.Expr | |
| IsHalideType Bool Source # | |
Defined in Language.Halide.Expr | |
| IsHalideType Double Source # | |
Defined in Language.Halide.Expr | |
| IsHalideType Float Source # | |
Defined in Language.Halide.Expr | |
Creating
mkExpr :: IsHalideType a => a -> Expr a Source #
Create a scalar expression from a Haskell value.
Create a named reduction variable.
For more information about reduction variables, see Halide::RDom.
undef :: forall a. IsHalideType a => Expr a Source #
Return an undef value of the given type.
For more information, see Halide::undef.
cast :: forall to from. (IsHalideType to, IsHalideType from) => Expr from -> Expr to Source #
Cast a scalar expression to a different type.
Use TypeApplications with this function, e.g. cast @Float x.
Inspecting
toIntImm :: IsHalideType a => Expr a -> Maybe Int Source #
Convert expression to integer immediate.
Tries to extract the value of an expression if it is a compile-time constant. If the expression
isn't known at compile-time of the Halide pipeline, returns Nothing.
printed :: IsHalideType a => Expr a -> Expr a Source #
Print the expression to stdout when it's evaluated.
This is useful for debugging Halide pipelines.
evaluate :: forall a. IsHalideType a => Expr a -> IO a Source #
Evaluate a scalar expression.
It should contain no parameters. If it does contain parameters, an exception will be thrown.
Comparisons
We can't use Eq and Ord instances here, because we want the comparison to happen
when the pipeline is run rather than when it's built. Hence, we define lifted version of
various comparison operators. Note, that infix versions of the these functions have the
same precedence as the normal comparison operators.
Functions
data Func (t :: FuncTy) (n :: Nat) (a :: Type) where Source #
A function in Halide. Conceptually, it can be thought of as a lazy
n-dimensional buffer of type a.
This is a wrapper around the Halide::Func
C++ type.
Constructors
| Func :: !(ForeignPtr CxxFunc) -> Func 'FuncTy n a | |
| Param :: !(IORef (Maybe (ForeignPtr CxxImageParam))) -> Func 'ParamTy n a |
Instances
Function type. It can either be FuncTy which means that we have defined the function ourselves,
or ParamTy which means that it's a parameter to our pipeline.
newtype Stage (n :: Nat) (a :: Type) Source #
A single definition of a Func.
Constructors
| Stage (ForeignPtr CxxStage) |
Instances
Creating
define :: (IsTuple (Arguments ts) i, All ((~) Var) ts, Length ts ~ n, KnownNat n, IsHalideType a) => Text -> i -> Expr a -> IO (Func 'FuncTy n a) Source #
Define a Halide function.
define "f" i e defines a Halide function called "f" such that f[i] = e.
Here, i is an n-element tuple of Var, i.e. the following are all valid:
>>>[x, y, z] <- mapM mkVar ["x", "y", "z"]>>>f1 <- define "f1" x (0 :: Expr Float)>>>f2 <- define "f2" (x, y) (0 :: Expr Float)>>>f3 <- define "f3" (x, y, z) (0 :: Expr Float)
update :: (IsTuple (Arguments ts) i, All ((~) (Expr Int32)) ts, Length ts ~ n, KnownNat n, IsHalideType a) => Func 'FuncTy n a -> i -> Expr a -> IO () Source #
Create an update definition for a Halide function.
update f i e creates an update definition for f that performs f[i] = e.
(!) :: (IsTuple (Arguments ts) i, All ((~) (Expr Int32)) ts, Length ts ~ n, KnownNat n, IsHalideType a) => Func t n a -> i -> Expr a infix 9 Source #
Apply a Halide function. Conceptually, f ! i is equivalent to f[i], i.e.
indexing into a lazy array.
Inspecting
getArgs :: (KnownNat n, IsHalideType a) => Func t n a -> IO [Var] Source #
Get the index arguments of the function.
The returned list contains exactly n elements.
hasUpdateDefinitions :: (KnownNat n, IsHalideType a) => Func t n a -> IO Bool Source #
getUpdateStage :: (KnownNat n, IsHalideType a) => Int -> Func 'FuncTy n a -> IO (Stage n a) Source #
Get a handle to an update step for the purposes of scheduling it.
Buffers
In the C interface of Halide, buffers are described by the C struct
halide_buffer_t. On the Haskell side,
we have HalideBuffer.
newtype HalideBuffer (n :: Nat) (a :: Type) Source #
An n-dimensional buffer of elements of type a.
Most pipelines use for input and output array arguments.Ptr (HalideBuffer n a)
Constructors
| HalideBuffer | |
Fields | |
Instances
To easily test out your pipeline, there are helper functions to create HalideBuffers without
worrying about the low-level representation.
allocaCpuBuffer :: forall n a b. (HasCallStack, KnownNat n, IsHalideType a) => [Int] -> (Ptr (HalideBuffer n a) -> IO b) -> IO b Source #
Temporary allocate a CPU buffer.
This is useful for testing and debugging when you need to allocate an output buffer for your pipeline. E.g.
allocaCpuBuffer[3, 3] $ out -> do myKernel out -- fill the buffer print =<<peekToListout -- print it for debugging
Buffers can also be converted to lists to easily print them for debugging.
class IsListPeek a where Source #
Specifies that a can be converted to a list. This is very similar to IsList except that
we read the list from a rather than converting directly.Ptr
Associated Types
type ListPeekElem a :: Type Source #
Methods
peekToList :: HasCallStack => Ptr a -> IO [ListPeekElem a] Source #
Instances
| IsHalideType a => IsListPeek (HalideBuffer 0 a) Source # | |
Defined in Language.Halide.Buffer Associated Types type ListPeekElem (HalideBuffer 0 a) Source # Methods peekToList :: Ptr (HalideBuffer 0 a) -> IO [ListPeekElem (HalideBuffer 0 a)] Source # | |
| IsHalideType a => IsListPeek (HalideBuffer 1 a) Source # | |
Defined in Language.Halide.Buffer Associated Types type ListPeekElem (HalideBuffer 1 a) Source # Methods peekToList :: Ptr (HalideBuffer 1 a) -> IO [ListPeekElem (HalideBuffer 1 a)] Source # | |
| IsHalideType a => IsListPeek (HalideBuffer 2 a) Source # | |
Defined in Language.Halide.Buffer Associated Types type ListPeekElem (HalideBuffer 2 a) Source # Methods peekToList :: Ptr (HalideBuffer 2 a) -> IO [ListPeekElem (HalideBuffer 2 a)] Source # | |
| IsHalideType a => IsListPeek (HalideBuffer 3 a) Source # | |
Defined in Language.Halide.Buffer Associated Types type ListPeekElem (HalideBuffer 3 a) Source # Methods peekToList :: Ptr (HalideBuffer 3 a) -> IO [ListPeekElem (HalideBuffer 3 a)] Source # | |
For production usage however, you don't want to work with lists. Instead, you probably want Halide
to work with your existing array data types. For this, we define IsHalideBuffer typeclass that
teaches Halide how to convert your data into a HalideBuffer. Depending on how you implement the
instance, this can be very efficient, because it need not involve any memory copying.
class (KnownNat n, IsHalideType a) => IsHalideBuffer t n a where Source #
Specifies that a type t can be used as an n-dimensional Halide buffer with elements of type a.
Methods
withHalideBufferImpl :: t -> (Ptr (HalideBuffer n a) -> IO b) -> IO b Source #
Instances
| IsHalideType a => IsHalideBuffer (Vector a) 1 a Source # | Storable vectors are one-dimensional buffers. This involves no copying. |
Defined in Language.Halide.Buffer Methods withHalideBufferImpl :: Vector a -> (Ptr (HalideBuffer 1 a) -> IO b) -> IO b Source # | |
| IsHalideType a => IsHalideBuffer [[[a]]] 3 a Source # | Lists can also act as Halide buffers. Use for testing only. |
Defined in Language.Halide.Buffer Methods withHalideBufferImpl :: [[[a]]] -> (Ptr (HalideBuffer 3 a) -> IO b) -> IO b Source # | |
| IsHalideType a => IsHalideBuffer [[a]] 2 a Source # | Lists can also act as Halide buffers. Use for testing only. |
Defined in Language.Halide.Buffer Methods withHalideBufferImpl :: [[a]] -> (Ptr (HalideBuffer 2 a) -> IO b) -> IO b Source # | |
| IsHalideType a => IsHalideBuffer [a] 1 a Source # | Lists can also act as Halide buffers. Use for testing only. |
Defined in Language.Halide.Buffer Methods withHalideBufferImpl :: [a] -> (Ptr (HalideBuffer 1 a) -> IO b) -> IO b Source # | |
| IsHalideType a => IsHalideBuffer (MVector RealWorld a) 1 a Source # | Storable vectors are one-dimensional buffers. This involves no copying. |
Defined in Language.Halide.Buffer Methods withHalideBufferImpl :: MVector RealWorld a -> (Ptr (HalideBuffer 1 a) -> IO b) -> IO b Source # | |
withHalideBuffer :: forall n a t b. IsHalideBuffer t n a => t -> (Ptr (HalideBuffer n a) -> IO b) -> IO b Source #
Treat a type t as a HalideBuffer and use it in an IO action.
This function is a simple wrapper around withHalideBufferImpl, except that the order of type parameters
is reversed. If you have TypeApplications extension enabled, this allows you to write
withHalideBuffer 3 Float yourBuffer to specify that you want a 3-dimensional buffer of Float.
There are also helper functions to simplify writing instances of IsHalideBuffer.
bufferFromPtrShapeStrides Source #
Arguments
| :: forall n a b. (HasCallStack, KnownNat n, IsHalideType a) | |
| => Ptr a | CPU pointer to the data |
| -> [Int] | Extents (in number of elements, not in bytes) |
| -> [Int] | Strides (in number of elements, not in bytes) |
| -> (Ptr (HalideBuffer n a) -> IO b) | Action to run |
| -> IO b |
Construct a HalideBuffer from a pointer to the data, a list of extents,
and a list of strides, and use it in an IO action.
This function throws a runtime error if the number of dimensions does not
match n.
Arguments
| :: (HasCallStack, KnownNat n, IsHalideType a) | |
| => Ptr a | CPU pointer to the data |
| -> [Int] | Extents (in number of elements, not in bytes) |
| -> (Ptr (HalideBuffer n a) -> IO b) | |
| -> IO b |
Similar to bufferFromPtrShapeStrides, but assumes column-major ordering of data.
Running the pipelines
There are a few ways how one can run a Halide pipeline.
The simplest way to build a Func and then call realize to evaluate it over a rectangular domain.
Arguments
| :: forall n a t b. (KnownNat n, IsHalideType a) | |
| => Func t n a | Function to evaluate |
| -> [Int] | Domain over which to evaluate |
| -> (Ptr (HalideBuffer n a) -> IO b) | What to do with the buffer afterwards. Note that the buffer is allocated only temporary, so do not return it directly. |
| -> IO b |
Evaluate this function over a rectangular domain.
Arguments
| :: forall n a t b. IsHalideBuffer t n a | |
| => t | Object to treat as a buffer |
| -> (Func 'ParamTy n a -> IO b) | What to do with the temporary buffer |
| -> IO b |
Wrap a buffer into a Func.
Suppose, we are defining a pipeline that adds together two vectors, and we'd like to call realize to
evaluate it directly, how do we pass the vectors to the Func? asBufferParam allows to do exactly this.
asBuffer [1, 2, 3] $ \a ->
asBuffer [4, 5, 6] $ \b -> do
i <- mkVar "i"
f <- define "vectorAdd" i $ a ! i + b ! i
realize f [3] $ \result ->
print =<< peekToList fThe drawback of calling realize all the time is that it's impossible to pass parameters to pipelines.
We can define pipelines that operate on buffers using asBufferParam, but we have to recompile the
pipeline for every new buffer.
A better way to handle pipeline parameters is to define a Haskell function that accepts Exprs
and Funcs as arguments and returns a Func. We can then pass this function to compile
(or compileForTarget), and it compile it into a Haskell function that can now be invoked with
normal scalars instead of Exprs and Ptr s instead of HalideBufferFuncs.
Arguments
| :: forall n a t f kernel. (IsFuncBuilder f t n a, Curry (Lowered (FunctionArguments f)) (Ptr (HalideBuffer n a) -> IO ()) kernel) | |
| => f | Function to compile |
| -> IO kernel | Compiled kernel |
Convert a function that builds a Halide Func into a normal Haskell function acccepting scalars and
HalideBuffers.
For example:
builder :: Expr Float -> Func 'ParamTy 1 Float -> IO (Func 'FuncTy 1 Float) builder scale inputVector = do i <-mkVar"i" scaledVector <-define"scaledVector" i $ scale * inputVector!i pure scaledVector
The builder function accepts a scalar parameter and a vector and scales the vector by the given factor.
We can now pass builder to compile:
scaler <-compilebuilderwithHalideBuffer1Float [1, 1, 1] $ inputVector ->allocaCpuBuffer[3] $ outputVector -> do -- invoke the kernel scaler 2.0 inputVector outputVector -- print the result print =<<peekToListoutputVector
Parameters
Similar to how we can specify the name of a variable in mkVar (or mkRVar) or function in define,
one can also specify the name of a pipeline parameter. This is achieved by using the ViewPatterns
extension together with the scalar and buffer helper functions.
buffer :: forall n a. (KnownNat n, IsHalideType a) => Text -> Func 'ParamTy n a -> Func 'ParamTy n a Source #
A view pattern to specify the name of a buffer argument.
Example usage:
>>>:{_ <- compile $ \(buffer "src" -> src) -> do i <- mkVar "i" define "dest" i $ (src ! i :: Expr Float) :}
or if we want to specify the dimension and type, we can use type applications:
>>>:{_ <- compile $ \(buffer @1 @Float "src" -> src) -> do i <- mkVar "i" define "dest" i $ src ! i :}
scalar :: forall a. IsHalideType a => Text -> Expr a -> Expr a Source #
Similar to buffer, but for scalar parameters.
Example usage:
>>>:{_ <- compile $ \(scalar @Float "a" -> a) -> do i <- mkVar "i" define "dest" i $ a :}
Another common thing to do with the parameters is to explicitly specify their shapes. For this, we expose the Dimension type:
Information about a buffer's dimension, such as the min, extent, and stride.
Constructors
| Dimension (ForeignPtr CxxDimension) |
dim :: forall n a. (HasCallStack, KnownNat n, IsHalideType a) => Int -> Func 'ParamTy n a -> IO Dimension Source #
Get a particular dimension of a pipeline parameter.
setMin :: Expr Int32 -> Dimension -> IO Dimension Source #
Set the min in a given dimension to equal the given expression. Setting the mins to zero may simplify some addressing math.
For more info, see Halide::Internal::Dimension::set_min.
setExtent :: Expr Int32 -> Dimension -> IO Dimension Source #
Set the extent in a given dimension to equal the given expression.
Halide will generate runtime errors for Buffers that fail this check.
For more info, see Halide::Internal::Dimension::set_extent.
setStride :: Expr Int32 -> Dimension -> IO Dimension Source #
Set the stride in a given dimension to equal the given expression.
This is particularly useful to set when vectorizing. Known strides for the vectorized dimensions generate better code.
For more info, see Halide::Internal::Dimension::set_stride.
Set estimates for autoschedulers.
Targets
The compilation target.
This is the Haskell counterpart of Halide::Target.
Constructors
| Target (ForeignPtr CxxTarget) |
hostTarget :: Target Source #
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.
gpuTarget :: Maybe Target Source #
Get the default GPU target. We first check for CUDA and then for OpenCL.
If neither of the two is usable, Nothing is returned.
compileForTarget :: forall n a t f kernel. (IsFuncBuilder f t n a, Curry (Lowered (FunctionArguments f)) (Ptr (HalideBuffer n a) -> IO ()) kernel) => Target -> f -> IO kernel Source #
Similar to compile, but the first argument lets you explicitly specify the compilation target.
An enum describing the type of device API.
This is the Haskell counterpart of Halide::DeviceAPI.
Constructors
| DeviceNone | |
| DeviceHost | |
| DeviceDefaultGPU | |
| DeviceCUDA | |
| DeviceOpenCL | |
| DeviceOpenGLCompute | |
| DeviceMetal | |
| DeviceHexagon | |
| DeviceHexagonDma | |
| DeviceD3D12Compute |
Instances
| Enum DeviceAPI Source # | |
Defined in Language.Halide.Target Methods succ :: DeviceAPI -> DeviceAPI # pred :: DeviceAPI -> DeviceAPI # fromEnum :: DeviceAPI -> Int # enumFrom :: DeviceAPI -> [DeviceAPI] # enumFromThen :: DeviceAPI -> DeviceAPI -> [DeviceAPI] # enumFromTo :: DeviceAPI -> DeviceAPI -> [DeviceAPI] # enumFromThenTo :: DeviceAPI -> DeviceAPI -> DeviceAPI -> [DeviceAPI] # | |
| Show DeviceAPI Source # | |
| Eq DeviceAPI Source # | |
| Ord DeviceAPI Source # | |
data TargetFeature Source #
Note: generated automatically using
cat $HALIDE_PATH/include/Halide.h | \ grep -E '.* = halide_target_feature_.*' | \ sed -E 's/^\s*(.*) = .*$/ | \1/g' | \ grep -v FeatureEnd
Constructors
Instances
Arguments
| :: TargetFeature | Feature to add |
| -> Target | Initial target |
| -> Target | New target |
Add a feature to target.
hasGpuFeature :: Target -> Bool Source #
Return whether a GPU compute runtime is enabled.
Checks whether gpuBlocks and similar are going to work.
For more info, see Target::has_gpu_feature.
hostSupportsTargetDevice Source #
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.
Scheduling
class (KnownNat n, IsHalideType a) => Schedulable f n a where Source #
Common scheduling functions
Methods
vectorize :: VarOrRVar -> f n a -> IO (f n a) Source #
Vectorize the dimension.
unroll :: VarOrRVar -> f n a -> IO (f n a) Source #
Unroll the dimension.
reorder :: [VarOrRVar] -> f n a -> IO (f n a) Source #
Reorder variables to have the given nesting order, from innermost out.
split :: TailStrategy -> VarOrRVar -> (VarOrRVar, VarOrRVar) -> Expr Int32 -> f n a -> IO (f n a) Source #
Split a dimension into inner and outer subdimensions with the given names, where the inner dimension
iterates from 0 to factor-1.
The inner and outer subdimensions can then be dealt with using the other scheduling calls. It's okay to reuse the old variable name as either the inner or outer variable. The first argument specifies how the tail should be handled if the split factor does not provably divide the extent.
fuse :: (VarOrRVar, VarOrRVar) -> VarOrRVar -> f n a -> IO (f n a) Source #
Join two dimensions into a single fused dimenion.
The fused dimension covers the product of the extents of the inner and outer dimensions given.
serial :: VarOrRVar -> f n a -> IO (f n a) Source #
Mark the dimension to be traversed serially
parallel :: VarOrRVar -> f n a -> IO (f n a) Source #
Mark the dimension to be traversed in parallel
specialize :: Expr Bool -> f n a -> IO (Stage n a) Source #
specializeFail :: Text -> f n a -> IO () Source #
gpuBlocks :: (IndexTuple i ts, 1 <= Length ts, Length ts <= 3) => DeviceAPI -> i -> f n a -> IO (f n a) Source #
gpuThreads :: (IndexTuple i ts, 1 <= Length ts, Length ts <= 3) => DeviceAPI -> i -> f n a -> IO (f n a) Source #
gpuLanes :: DeviceAPI -> VarOrRVar -> f n a -> IO (f n a) Source #
computeWith :: LoopAlignStrategy -> f n a -> LoopLevel t -> IO () Source #
Schedule the iteration over this stage to be fused with another stage from outermost loop to a given LoopLevel.
For more info, see Halide::Stage::compute_with.
Instances
data TailStrategy Source #
Different ways to handle a tail case in a split when the split factor does not provably divide the extent.
This is the Haskell counterpart of Halide::TailStrategy.
Constructors
| TailRoundUp | Round up the extent to be a multiple of the split factor. Not legal for RVars, as it would change the meaning of the algorithm.
|
| TailGuardWithIf | Guard the inner loop with an if statement that prevents evaluation beyond the original extent. Always legal. The if statement is treated like a boundary condition, and factored out into a loop epilogue if possible.
|
| TailPredicate | Guard the loads and stores in the loop with an if statement that prevents evaluation beyond the original extent. Always legal. The if statement is treated like a boundary condition, and factored out into a loop epilogue if possible. * Pros: no redundant re-evaluation; does not constrain input or output sizes. * Cons: increases code size due to separate tail-case handling. |
| TailPredicateLoads | Guard the loads in the loop with an if statement that prevents evaluation beyond the original extent. Only legal for innermost splits. Not legal for RVars, as it would change the meaning of the algorithm. The if statement is treated like a boundary condition, and factored out into a loop epilogue if possible. * Pros: does not constrain input sizes, output size constraints are simpler than full predication. * Cons: increases code size due to separate tail-case handling, constrains the output size to be a multiple of the split factor. |
| TailPredicateStores | Guard the stores in the loop with an if statement that prevents evaluation beyond the original extent. Only legal for innermost splits. Not legal for RVars, as it would change the meaning of the algorithm. The if statement is treated like a boundary condition, and factored out into a loop epilogue if possible. * Pros: does not constrain output sizes, input size constraints are simpler than full predication. * Cons: increases code size due to separate tail-case handling, constraints the input size to be a multiple of the split factor. |
| TailShiftInwards | Prevent evaluation beyond the original extent by shifting the tail case inwards, re-evaluating some points near the end. Only legal for pure variables in pure definitions. If the inner loop is very simple, the tail case is treated like a boundary condition and factored out into an epilogue. This is a good trade-off between several factors. Like |
| TailAuto | For pure definitions use For pure vars in update definitions use |
Instances
data LoopLevel (t :: LoopLevelTy) where Source #
A reference to a site in a Halide statement at the top of the body of a particular for loop.
Constructors
| InlinedLoopLevel :: LoopLevel 'InlinedTy | |
| RootLoopLevel :: LoopLevel 'RootTy | |
| LoopLevel :: !(ForeignPtr CxxLoopLevel) -> LoopLevel 'LockedTy |
data LoopAlignStrategy Source #
Different ways to handle the case when the start/end of the loops of stages computed with (fused) are not aligned.
Constructors
| LoopAlignStart | Shift the start of the fused loops to align. |
| LoopAlignEnd | Shift the end of the fused loops to align. |
| LoopNoAlign |
|
| LoopAlignAuto | By default, LoopAlignStrategy is set to |
Instances
computeRoot :: (KnownNat n, IsHalideType a) => Func t n a -> IO (Func t n a) Source #
Compute all of this function once ahead of time.
See Halide::Func::compute_root for more info.
getStage :: (KnownNat n, IsHalideType a) => Func t n a -> IO (Stage n a) Source #
Get the pure stage of a Func for the purposes of scheduling it.
getLoopLevel :: (KnownNat n, IsHalideType a) => Func t n a -> Expr Int32 -> IO (LoopLevel 'LockedTy) Source #
Same as getLoopLevelAtStage except that the stage is -1.
Arguments
| :: (KnownNat n, IsHalideType a) | |
| => Func t n a | |
| -> Expr Int32 | |
| -> Int | update index |
| -> IO (LoopLevel 'LockedTy) |
Identify the loop nest corresponding to some dimension of some function.
asUsed :: (KnownNat n, IsHalideType a) => Func t n a -> IO (Func 'FuncTy n a) Source #
Create and return a global identity wrapper, which wraps all calls to this Func by any other Func.
If a global wrapper already exists, returns it. The global identity wrapper is only used by callers for which no custom wrapper has been specified.
asUsedBy :: (KnownNat n, KnownNat m, IsHalideType a, IsHalideType b) => Func t1 n a -> Func 'FuncTy m b -> IO (Func 'FuncTy n a) Source #
Creates and returns a new identity Func that wraps this Func.
During compilation, Halide replaces all calls to this Func done by f with calls to the wrapper.
If this Func is already wrapped for use in f, will return the existing wrapper.
For more info, see Halide::Func::in.
copyToDevice :: (KnownNat n, IsHalideType a) => DeviceAPI -> Func t n a -> IO (Func t n a) Source #
Declare that this function should be implemented by a call to halide_buffer_copy with the given
target device API.
Asserts that the Func has a pure definition which is a simple call to a single input, and no update
definitions. The wrapper Funcs returned by asUsed are suitable candidates. Consumes all pure variables,
and rewrites the Func to have an extern definition that calls halide_buffer_copy.
copyToHost :: (KnownNat n, IsHalideType a) => Func t n a -> IO (Func t n a) Source #
Same as copyToDevice DeviceHost
storeAt :: (KnownNat n, IsHalideType a) => Func 'FuncTy n a -> LoopLevel t -> IO (Func 'FuncTy n a) Source #
Allocate storage for this function within a particular loop level.
Scheduling storage is optional, and can be used to separate the loop level at which storage is allocated from the loop level at which computation occurs to trade off between locality and redundant work.
For more info, see Halide::Func::store_at.
computeAt :: (KnownNat n, IsHalideType a) => Func 'FuncTy n a -> LoopLevel t -> IO (Func 'FuncTy n a) Source #
Schedule a function to be computed within the iteration over a given loop level.
For more info, see Halide::Func::compute_at.
Arguments
| :: (KnownNat n, IsHalideType a) | |
| => Expr Int32 | index variable |
| -> Expr Int32 |
|
| -> Expr Int32 |
|
| -> Func t n a | |
| -> IO () |
Split a dimension by the given factor, then unroll the inner dimension.
This is how you unroll a loop of unknown size by some constant factor. After
this call, var refers to the outer dimension of the split.
unroll
:: (KnownNat n, IsHalideType a)
=> TailStrategy
-> Func t n a
-> Expr Int32
-- ^ Variable var to vectorize
-> Expr Int32
-- ^ Split factor
-> IO ()
unroll strategy func var factor =
withFunc func $ f ->
asVarOrRVar var $ x ->
asExpr factor $ n ->
[C.throwBlock| void {
$(Halide::Func* f)->unroll(*$(Halide::VarOrRVar* x), *$(Halide::Expr* n),
static_castHalide::TailStrategy($(int tail)));
} |]
where
tail = fromIntegral (fromEnum strategy)
Reorder variables to have the given nesting order, from innermost out. reorder :: forall t n a i ts . ( IsTuple (Arguments ts) i , All ((~) (Expr Int32)) ts , Length ts ~ n , KnownNat n , IsHalideType a ) => Func t n a -> i -> IO () reorder func args = asVectorOf @((~) (Expr Int32)) asVarOrRVar (fromTuple args) $ v -> do withFunc func $ f -> [C.throwBlock| void { $(Halide::Func* f)->reorder(*$(std::vectorHalide::VarOrRVar* v)); } |]
Statically declare the range over which the function will be evaluated in the general case.
This provides a basis for the auto scheduler to make trade-offs and scheduling decisions. The auto generated schedules might break when the sizes of the dimensions are very different from the estimates specified. These estimates are used only by the auto scheduler if the function is a pipeline output.
Arguments
| :: (KnownNat n, IsHalideType a) | |
| => Expr Int32 | index variable |
| -> Expr Int32 |
|
| -> Expr Int32 |
|
| -> Func t n a | |
| -> IO () |
Statically declare the range over which a function should be evaluated.
This can let Halide perform some optimizations. E.g. if you know there are going to be 4 color channels, you can completely vectorize the color channel dimension without the overhead of splitting it up. If bounds inference decides that it requires more of this function than the bounds you have stated, a runtime error will occur when you try to run your pipeline.
Debugging / Tracing
For debugging, it's often useful to observe the value of an expression when it's evaluated. If you
have a complex expression that does not depend on any buffers or indices, you can evaluate it.
| However, often an expression is only used within a definition of a pipeline, and it's impossible to
call evaluate on it. In such cases, it can be wrapped with printed to indicate to Halide that the
value of the expression should be dumped to screen when it's computed.
prettyLoopNest :: (KnownNat n, IsHalideType r) => Func t n r -> IO Text Source #
Write out the loop nests specified by the schedule for this function.
Helpful for understanding what a schedule is doing.
For more info, see
Halide::Func::print_loop_nest
printLoopNest :: (KnownNat n, IsHalideType r) => Func n r -> IO ()
printLoopNest func = withFunc func $ f ->
[C.exp| void { $(Halide::Func* f)->print_loop_nest() } |]
Get the loop nests specified by the schedule for this function.
Helpful for understanding what a schedule is doing.
For more info, see
Halide::Func::print_loop_nest
compileToLoweredStmt :: forall n a t f. IsFuncBuilder f t n a => StmtOutputFormat -> Target -> f -> IO Text Source #
Get the internal representation of lowered code.
Useful for analyzing and debugging scheduling. Can emit HTML or plain text.
data StmtOutputFormat Source #
Format in which to return the lowered code.
Instances
| Enum StmtOutputFormat Source # | |
Defined in Language.Halide.Kernel Methods succ :: StmtOutputFormat -> StmtOutputFormat # pred :: StmtOutputFormat -> StmtOutputFormat # toEnum :: Int -> StmtOutputFormat # fromEnum :: StmtOutputFormat -> Int # enumFrom :: StmtOutputFormat -> [StmtOutputFormat] # enumFromThen :: StmtOutputFormat -> StmtOutputFormat -> [StmtOutputFormat] # enumFromTo :: StmtOutputFormat -> StmtOutputFormat -> [StmtOutputFormat] # enumFromThenTo :: StmtOutputFormat -> StmtOutputFormat -> StmtOutputFormat -> [StmtOutputFormat] # | |
| Show StmtOutputFormat Source # | |
Defined in Language.Halide.Kernel Methods showsPrec :: Int -> StmtOutputFormat -> ShowS # show :: StmtOutputFormat -> String # showList :: [StmtOutputFormat] -> ShowS # | |
| Eq StmtOutputFormat Source # | |
Defined in Language.Halide.Kernel Methods (==) :: StmtOutputFormat -> StmtOutputFormat -> Bool # (/=) :: StmtOutputFormat -> StmtOutputFormat -> Bool # | |
data TraceEvent Source #
Constructors
| TraceEvent | |
Fields
| |
Instances
| Show TraceEvent Source # | |
Defined in Language.Halide.Trace Methods showsPrec :: Int -> TraceEvent -> ShowS # show :: TraceEvent -> String # showList :: [TraceEvent] -> ShowS # | |
data TraceEventCode Source #
Haskell counterpart of halide_trace_event_code_t.
Constructors
| TraceLoad | |
| TraceStore | |
| TraceBeginRealization | |
| TraceEndRealization | |
| TraceProduce | |
| TraceEndProduce | |
| TraceConsume | |
| TraceEndConsume | |
| TraceBeginPipeline | |
| TraceEndPipeline | |
| TraceTag |
Instances
data TraceLoadStoreContents Source #
Constructors
| TraceLoadStoreContents | |
Fields
| |
Instances
| Show TraceLoadStoreContents Source # | |
Defined in Language.Halide.Trace Methods showsPrec :: Int -> TraceLoadStoreContents -> ShowS # show :: TraceLoadStoreContents -> String # showList :: [TraceLoadStoreContents] -> ShowS # | |
Arguments
| :: (KnownNat n, IsHalideType a) | |
| => (TraceEvent -> IO ()) | Custom trace function |
| -> Func t n a | For which func to enable it |
| -> IO b | For the duration of which computation to enable it |
| -> IO b |
traceStores :: (KnownNat n, IsHalideType a) => Func t n a -> IO (Func t n a) Source #
traceLoads :: (KnownNat n, IsHalideType a) => Func t n a -> IO (Func t n a) Source #
collectIterationOrder :: (KnownNat n, IsHalideType a) => (TraceEventCode -> Bool) -> Func t n a -> IO b -> IO ([[Int]], b) Source #
Type helpers
class (ToTuple a ~ t, FromTuple t ~ a) => IsTuple a t | a -> t, t -> a where Source #
Specifies that there is an isomorphism between a type a and a tuple t.
We use this class to convert between Arguments and normal tuples.
type family ToTuple t where ... Source #
Type family that maps to the corresponding tuple type.Arguments ts
type family FromTuple t Source #
Type family that maps tuples to the corresponding type. This is essentially the inverse
of Arguments tsToTuple.
Instances
| type FromTuple () Source # | |
Defined in Language.Halide.Type type FromTuple () | |
| type FromTuple (Expr a) Source # | |
Defined in Language.Halide.Expr | |
| type FromTuple (a1, a2) Source # | |
Defined in Language.Halide.Type type FromTuple (a1, a2) | |
| type FromTuple (a1, a2, a3) Source # | |
Defined in Language.Halide.Type type FromTuple (a1, a2, a3) | |
| type FromTuple (a1, a2, a3, a4) Source # | |
Defined in Language.Halide.Type type FromTuple (a1, a2, a3, a4) | |
| type FromTuple (a1, a2, a3, a4, a5) Source # | |
Defined in Language.Halide.Type type FromTuple (a1, a2, a3, a4, a5) | |
type IndexTuple i ts = (IsTuple (Arguments ts) i, All ((~) (Expr Int32)) ts) Source #
Specifies that i is a tuple of .Expr Int32
ts are deduced from i, so you don't have to specify them explicitly.
type family Length (xs :: [k]) :: Nat where ... Source #
A type family that returns the length of a type-level list.
type family All (c :: Type -> Constraint) (ts :: [Type]) :: Constraint where ... Source #
Apply constraint to all types in a list.
Internal
compileToCallable :: forall n a t f inputs output. (IsFuncBuilder f t n a, Lowered (FunctionArguments f) ~ inputs, Ptr (HalideBuffer n a) ~ output) => Target -> f -> IO (Callable inputs output) Source #
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
testOpenCL :: IO () Source #
Similar to testCUDA but for FeatureOpenCL.
data SomeLoopLevel where Source #
Constructors
| SomeLoopLevel :: LoopLevel t -> SomeLoopLevel |
Instances
| Show SomeLoopLevel Source # | |
Defined in Language.Halide.LoopLevel Methods showsPrec :: Int -> SomeLoopLevel -> ShowS # show :: SomeLoopLevel -> String # showList :: [SomeLoopLevel] -> ShowS # | |
| Eq SomeLoopLevel Source # | |
Defined in Language.Halide.LoopLevel Methods (==) :: SomeLoopLevel -> SomeLoopLevel -> Bool # (/=) :: SomeLoopLevel -> SomeLoopLevel -> Bool # | |
data RawHalideBuffer Source #
The low-level untyped Haskell analogue of halide_buffer_t.
It's quite difficult to use RawHalideBuffer correctly, and misusage can result in crashes and
segmentation faults. Hence, prefer the higher-level HalideBuffer wrapper for all your code
Constructors
| RawHalideBuffer | |
Fields
| |
Instances
| Storable RawHalideBuffer Source # | |
Defined in Language.Halide.Buffer Methods sizeOf :: RawHalideBuffer -> Int # alignment :: RawHalideBuffer -> Int # peekElemOff :: Ptr RawHalideBuffer -> Int -> IO RawHalideBuffer # pokeElemOff :: Ptr RawHalideBuffer -> Int -> RawHalideBuffer -> IO () # peekByteOff :: Ptr b -> Int -> IO RawHalideBuffer # pokeByteOff :: Ptr b -> Int -> RawHalideBuffer -> IO () # peek :: Ptr RawHalideBuffer -> IO RawHalideBuffer # poke :: Ptr RawHalideBuffer -> RawHalideBuffer -> IO () # | |
| Show RawHalideBuffer Source # | |
Defined in Language.Halide.Buffer Methods showsPrec :: Int -> RawHalideBuffer -> ShowS # show :: RawHalideBuffer -> String # showList :: [RawHalideBuffer] -> ShowS # | |
| Eq RawHalideBuffer Source # | |
Defined in Language.Halide.Buffer Methods (==) :: RawHalideBuffer -> RawHalideBuffer -> Bool # (/=) :: RawHalideBuffer -> RawHalideBuffer -> Bool # | |
data HalideDimension Source #
Information about a dimension in a buffer.
It is the Haskell analogue of halide_dimension_t.
Constructors
| HalideDimension | |
Fields
| |
Instances
data HalideDeviceInterface Source #
Haskell analogue of halide_device_interface_t.
Arguments
| :: Integral a | |
| => [a] | Extents |
| -> [a] |
Get strides corresponding to row-major ordering
Arguments
| :: Integral a | |
| => [a] | Extents |
| -> [a] |
Get strides corresponding to column-major ordering.
isDeviceDirty :: Ptr RawHalideBuffer -> IO Bool Source #
Do we have changes on the device the have not been copied to the host?
isHostDirty :: Ptr RawHalideBuffer -> IO Bool Source #
Do we have changes on the device the have not been copied to the host?
bufferCopyToHost :: Ptr RawHalideBuffer -> IO () Source #
Copy the underlying memory from device to host.
Type of dimension that tells which transformations are legal on it.
Constructors
| DimPureVar | |
| DimPureRVar | |
| DimImpureRVar |
Instances
Specifies how loop values are traversed.
Constructors
| ForSerial | |
| ForParallel | |
| ForVectorized | |
| ForUnrolled | |
| ForExtern | |
| ForGPUBlock | |
| ForGPUThread | |
| ForGPULane |
Instances
data SplitContents Source #
Constructors
| SplitContents | |
Fields
| |
Instances
| Show SplitContents Source # | |
Defined in Language.Halide.Schedule Methods showsPrec :: Int -> SplitContents -> ShowS # show :: SplitContents -> String # showList :: [SplitContents] -> ShowS # | |
data FuseContents Source #
Instances
| Show FuseContents Source # | |
Defined in Language.Halide.Schedule Methods showsPrec :: Int -> FuseContents -> ShowS # show :: FuseContents -> String # showList :: [FuseContents] -> ShowS # | |
| Eq FuseContents Source # | |
Defined in Language.Halide.Schedule | |
Constructors
| SplitVar !SplitContents | |
| FuseVars !FuseContents |
Instances
| Storable Split Source # | |
| Show Split Source # | |
Constructors
| Bound | |
data StorageDim Source #
Constructors
| StorageDim | |
Fields
| |
Instances
| Show StorageDim Source # | |
Defined in Language.Halide.Schedule Methods showsPrec :: Int -> StorageDim -> ShowS # show :: StorageDim -> String # showList :: [StorageDim] -> ShowS # | |
Instances
| Storable FusedPair Source # | |
Defined in Language.Halide.Schedule | |
| Show FusedPair Source # | |
| Eq FusedPair Source # | |
data FuseLoopLevel Source #
Constructors
| FuseLoopLevel !SomeLoopLevel |
Instances
| Show FuseLoopLevel Source # | |
Defined in Language.Halide.Schedule Methods showsPrec :: Int -> FuseLoopLevel -> ShowS # show :: FuseLoopLevel -> String # showList :: [FuseLoopLevel] -> ShowS # | |
| Eq FuseLoopLevel Source # | |
Defined in Language.Halide.Schedule Methods (==) :: FuseLoopLevel -> FuseLoopLevel -> Bool # (/=) :: FuseLoopLevel -> FuseLoopLevel -> Bool # | |
data StageSchedule Source #
Constructors
| StageSchedule | |
Fields
| |
Instances
| Show StageSchedule Source # | |
Defined in Language.Halide.Schedule Methods showsPrec :: Int -> StageSchedule -> ShowS # show :: StageSchedule -> String # showList :: [StageSchedule] -> ShowS # | |
data ReductionVariable Source #
Constructors
| ReductionVariable | |
Instances
| Storable ReductionVariable Source # | |
Defined in Language.Halide.Schedule Methods sizeOf :: ReductionVariable -> Int # alignment :: ReductionVariable -> Int # peekElemOff :: Ptr ReductionVariable -> Int -> IO ReductionVariable # pokeElemOff :: Ptr ReductionVariable -> Int -> ReductionVariable -> IO () # peekByteOff :: Ptr b -> Int -> IO ReductionVariable # pokeByteOff :: Ptr b -> Int -> ReductionVariable -> IO () # peek :: Ptr ReductionVariable -> IO ReductionVariable # poke :: Ptr ReductionVariable -> ReductionVariable -> IO () # | |
| Show ReductionVariable Source # | |
Defined in Language.Halide.Schedule Methods showsPrec :: Int -> ReductionVariable -> ShowS # show :: ReductionVariable -> String # showList :: [ReductionVariable] -> ShowS # | |
data PrefetchDirective Source #
Constructors
| PrefetchDirective | |
Fields
| |
Instances
| Storable PrefetchDirective Source # | |
Defined in Language.Halide.Schedule Methods sizeOf :: PrefetchDirective -> Int # alignment :: PrefetchDirective -> Int # peekElemOff :: Ptr PrefetchDirective -> Int -> IO PrefetchDirective # pokeElemOff :: Ptr PrefetchDirective -> Int -> PrefetchDirective -> IO () # peekByteOff :: Ptr b -> Int -> IO PrefetchDirective # pokeByteOff :: Ptr b -> Int -> PrefetchDirective -> IO () # peek :: Ptr PrefetchDirective -> IO PrefetchDirective # poke :: Ptr PrefetchDirective -> PrefetchDirective -> IO () # | |
| Show PrefetchDirective Source # | |
Defined in Language.Halide.Schedule Methods showsPrec :: Int -> PrefetchDirective -> ShowS # show :: PrefetchDirective -> String # showList :: [PrefetchDirective] -> ShowS # | |
getStageSchedule :: (KnownNat n, IsHalideType a) => Stage n a -> IO StageSchedule Source #
data AutoScheduler Source #
Constructors
| Adams2019 | |
| Li2018 | |
| Mullapudi2016 |
Instances
| Show AutoScheduler Source # | |
Defined in Language.Halide.Schedule Methods showsPrec :: Int -> AutoScheduler -> ShowS # show :: AutoScheduler -> String # showList :: [AutoScheduler] -> ShowS # | |
| Eq AutoScheduler Source # | |
Defined in Language.Halide.Schedule Methods (==) :: AutoScheduler -> AutoScheduler -> Bool # (/=) :: AutoScheduler -> AutoScheduler -> Bool # | |
loadAutoScheduler :: AutoScheduler -> IO () Source #
applyAutoScheduler :: (KnownNat n, IsHalideType a) => AutoScheduler -> Target -> Func t n a -> IO Text Source #
applySplits :: (KnownNat n, IsHalideType a) => [Split] -> Stage n a -> IO () Source #
applySchedule :: (KnownNat n, IsHalideType a) => StageSchedule -> Stage n a -> IO () Source #
type IsFuncBuilder f t n a = (All ValidParameter (FunctionArguments f), All ValidArgument (Lowered (FunctionArguments f)), UnCurry f (FunctionArguments f) (FunctionReturn f), PrepareParameters (FunctionArguments f), ReturnsFunc f t n a, KnownNat (Length (FunctionArguments f)), KnownNat (Length (Lowered (FunctionArguments f)))) Source #
class (FunctionReturn f ~ IO (Func t n a), IsHalideType a, KnownNat n) => ReturnsFunc f t n a | f -> t n a Source #
Instances
| (FunctionReturn f ~ IO (Func t n a), IsHalideType a, KnownNat n) => ReturnsFunc f t n a Source # | |
Defined in Language.Halide.Kernel | |
type family FunctionArguments (f :: Type) :: [Type] where ... Source #
Return the list of arguments to of a function type.
Equations
| FunctionArguments (a -> b) = a ': FunctionArguments b | |
| FunctionArguments a = '[] |
type family FunctionReturn (f :: Type) :: Type where ... Source #
Get the return type of a function.
Equations
| FunctionReturn (a -> b) = FunctionReturn b | |
| FunctionReturn a = a |
class Curry (args :: [Type]) (r :: Type) (f :: Type) | args r -> f where Source #
A helper typeclass to convert a function that takes Arguments as input
into a normal curried function. This is the inverse of UnCurry.
For instance, if we have a function f :: Arguments '[Int, Float] -> Double, then
it will be converted to f' :: Int -> Float -> Double.
class UnCurry (f :: Type) (args :: [Type]) (r :: Type) | args r -> f where Source #
A helper typeclass to convert a normal curried function to a function that
takes Arguments as input.
For instance, if we have a function f :: Int -> Float -> Double, then it
will be converted to f' :: Arguments '[Int, Float] -> Double.
Instances
| (FunctionArguments f ~ ('[] :: [Type]), FunctionReturn f ~ r, f ~ r) => UnCurry f ('[] :: [Type]) r Source # | |
Defined in Language.Halide.Type | |
| UnCurry f args r => UnCurry (a -> f) (a ': args) r Source # | |
Defined in Language.Halide.Type | |
inline-c helpers
importHalide :: DecsQ Source #
One stop function to include all the neccessary machinery to call Halide functions via inline-c.
Put importHalide somewhere at the beginning of the file and enjoy using the C++ interface of
Halide via inline-c quasiquotes.
data CxxParameter Source #
Haskell counterpart of Halide::Internal::Parameter.
data CxxImageParam Source #
Haskell counterpart of Halide::ImageParam.
Haskell counterpart of Halide::Stage.
data CxxDimension Source #
Haskell counterpart of Halide::Internal::Dimension.
data CxxLoopLevel Source #
Haskell counterpart of Halide::LoopLevel
Convenience re-exports
32-bit signed integer type
Instances
A value of type represents a pointer to an object, or an
array of objects, which may be marshalled to or from Haskell values
of type Ptr aa.
The type a will often be an instance of class
Storable which provides the marshalling operations.
However this is not essential, and you can provide your own operations
to access the pointer. For example you might write small foreign
functions to get or set the fields of a C struct.
Instances
| Generic1 (URec (Ptr ()) :: k -> Type) | |
| Foldable (UAddr :: TYPE LiftedRep -> Type) | Since: base-4.9.0.0 |
Defined in Data.Foldable Methods fold :: Monoid m => UAddr m -> m # foldMap :: Monoid m => (a -> m) -> UAddr a -> m # foldMap' :: Monoid m => (a -> m) -> UAddr a -> m # foldr :: (a -> b -> b) -> b -> UAddr a -> b # foldr' :: (a -> b -> b) -> b -> UAddr a -> b # foldl :: (b -> a -> b) -> b -> UAddr a -> b # foldl' :: (b -> a -> b) -> b -> UAddr a -> b # foldr1 :: (a -> a -> a) -> UAddr a -> a # foldl1 :: (a -> a -> a) -> UAddr a -> a # elem :: Eq a => a -> UAddr a -> Bool # maximum :: Ord a => UAddr a -> a # minimum :: Ord a => UAddr a -> a # | |
| Traversable (UAddr :: Type -> Type) | Since: base-4.9.0.0 |
| Storable (Ptr a) | Since: base-2.1 |
| Show (Ptr a) | Since: base-2.1 |
| Eq (Ptr a) | Since: base-2.1 |
| Ord (Ptr a) | Since: base-2.1 |
| Hashable (Ptr a) | |
Defined in Data.Hashable.Class | |
| Prim (Ptr a) | |
Defined in Data.Primitive.Types Methods alignment# :: Ptr a -> Int# # indexByteArray# :: ByteArray# -> Int# -> Ptr a # readByteArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Ptr a #) # writeByteArray# :: MutableByteArray# s -> Int# -> Ptr a -> State# s -> State# s # setByteArray# :: MutableByteArray# s -> Int# -> Int# -> Ptr a -> State# s -> State# s # indexOffAddr# :: Addr# -> Int# -> Ptr a # readOffAddr# :: Addr# -> Int# -> State# s -> (# State# s, Ptr a #) # writeOffAddr# :: Addr# -> Int# -> Ptr a -> State# s -> State# s # setOffAddr# :: Addr# -> Int# -> Int# -> Ptr a -> State# s -> State# s # | |
| Functor (URec (Ptr ()) :: TYPE LiftedRep -> Type) | Since: base-4.9.0.0 |
| Generic (URec (Ptr ()) p) | |
| Eq (URec (Ptr ()) p) | Since: base-4.9.0.0 |
| Ord (URec (Ptr ()) p) | Since: base-4.9.0.0 |
Defined in GHC.Generics Methods compare :: URec (Ptr ()) p -> URec (Ptr ()) p -> Ordering # (<) :: URec (Ptr ()) p -> URec (Ptr ()) p -> Bool # (<=) :: URec (Ptr ()) p -> URec (Ptr ()) p -> Bool # (>) :: URec (Ptr ()) p -> URec (Ptr ()) p -> Bool # (>=) :: URec (Ptr ()) p -> URec (Ptr ()) p -> Bool # max :: URec (Ptr ()) p -> URec (Ptr ()) p -> URec (Ptr ()) p # min :: URec (Ptr ()) p -> URec (Ptr ()) p -> URec (Ptr ()) p # | |
| data URec (Ptr ()) (p :: k) | Used for marking occurrences of Since: base-4.9.0.0 |
| type Rep1 (URec (Ptr ()) :: k -> Type) | Since: base-4.9.0.0 |
Defined in GHC.Generics | |
| type Rep (URec (Ptr ()) p) | Since: base-4.9.0.0 |
Defined in GHC.Generics | |