Copyright | (c) Tom Westerhout 2023 |
---|---|
Safe Haskell | Safe-Inferred |
Language | GHC2021 |
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 Expr
s, 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.
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.
halideTypeFor, toCxxExpr
Instances
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.
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
.
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)
Instances
To easily test out your pipeline, there are helper functions to create HalideBuffer
s 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 =<<peekToList
out -- 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
type ListPeekElem a :: Type Source #
peekToList :: HasCallStack => Ptr a -> IO [ListPeekElem a] Source #
Instances
IsHalideType a => IsListPeek (HalideBuffer 0 a) Source # | |
Defined in Language.Halide.Buffer type ListPeekElem (HalideBuffer 0 a) Source # peekToList :: Ptr (HalideBuffer 0 a) -> IO [ListPeekElem (HalideBuffer 0 a)] Source # | |
IsHalideType a => IsListPeek (HalideBuffer 1 a) Source # | |
Defined in Language.Halide.Buffer type ListPeekElem (HalideBuffer 1 a) Source # peekToList :: Ptr (HalideBuffer 1 a) -> IO [ListPeekElem (HalideBuffer 1 a)] Source # | |
IsHalideType a => IsListPeek (HalideBuffer 2 a) Source # | |
Defined in Language.Halide.Buffer type ListPeekElem (HalideBuffer 2 a) Source # peekToList :: Ptr (HalideBuffer 2 a) -> IO [ListPeekElem (HalideBuffer 2 a)] Source # | |
IsHalideType a => IsListPeek (HalideBuffer 3 a) Source # | |
Defined in Language.Halide.Buffer type ListPeekElem (HalideBuffer 3 a) Source # 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
.
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 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 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 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 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 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 #
:: 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
.
:: (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.
:: 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.
:: 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 f
The 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 Expr
s
and Func
s 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 Expr
s and Ptr
s instead of HalideBuffer
Func
s.
:: 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
HalideBuffer
s.
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 <-compile
builderwithHalideBuffer
1
Float [1, 1, 1] $ inputVector ->allocaCpuBuffer
[3] $ outputVector -> do -- invoke the kernel scaler 2.0 inputVector outputVector -- print the result print =<<peekToList
outputVector
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.
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
.
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
.
DeviceNone | |
DeviceHost | |
DeviceDefaultGPU | |
DeviceCUDA | |
DeviceOpenCL | |
DeviceOpenGLCompute | |
DeviceMetal | |
DeviceHexagon | |
DeviceHexagonDma | |
DeviceD3D12Compute |
Instances
Enum DeviceAPI Source # | |
Defined in Language.Halide.Target 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 # | |
Defined in Language.Halide.Target |
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
Instances
:: 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
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
.
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.
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.
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
.
:: (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 Func
s 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.
:: (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.
:: (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 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 showsPrec :: Int -> StmtOutputFormat -> ShowS # show :: StmtOutputFormat -> String # showList :: [StmtOutputFormat] -> ShowS # | |
Eq StmtOutputFormat Source # | |
Defined in Language.Halide.Kernel (==) :: StmtOutputFormat -> StmtOutputFormat -> Bool # (/=) :: StmtOutputFormat -> StmtOutputFormat -> Bool # |
data TraceEvent Source #
TraceEvent | |
|
Instances
Show TraceEvent Source # | |
Defined in Language.Halide.Trace showsPrec :: Int -> TraceEvent -> ShowS # show :: TraceEvent -> String # showList :: [TraceEvent] -> ShowS # |
data TraceEventCode Source #
Haskell counterpart of halide_trace_event_code_t
.
TraceLoad | |
TraceStore | |
TraceBeginRealization | |
TraceEndRealization | |
TraceProduce | |
TraceEndProduce | |
TraceConsume | |
TraceEndConsume | |
TraceBeginPipeline | |
TraceEndPipeline | |
TraceTag |
Instances
data TraceLoadStoreContents Source #
TraceLoadStoreContents | |
|
Instances
Show TraceLoadStoreContents Source # | |
Defined in Language.Halide.Trace showsPrec :: Int -> TraceLoadStoreContents -> ShowS # show :: TraceLoadStoreContents -> String # showList :: [TraceLoadStoreContents] -> ShowS # |
:: (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 #
SomeLoopLevel :: LoopLevel t -> SomeLoopLevel |
Instances
Show SomeLoopLevel Source # | |
Defined in Language.Halide.LoopLevel showsPrec :: Int -> SomeLoopLevel -> ShowS # show :: SomeLoopLevel -> String # showList :: [SomeLoopLevel] -> ShowS # | |
Eq SomeLoopLevel Source # | |
Defined in Language.Halide.LoopLevel (==) :: 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
RawHalideBuffer | |
|
Instances
Storable RawHalideBuffer Source # | |
Defined in Language.Halide.Buffer 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 showsPrec :: Int -> RawHalideBuffer -> ShowS # show :: RawHalideBuffer -> String # showList :: [RawHalideBuffer] -> ShowS # | |
Eq RawHalideBuffer Source # | |
Defined in Language.Halide.Buffer (==) :: 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
.
HalideDimension | |
|
Instances
Storable HalideDimension Source # | |
Defined in Language.Halide.Buffer sizeOf :: HalideDimension -> Int # alignment :: HalideDimension -> Int # peekElemOff :: Ptr HalideDimension -> Int -> IO HalideDimension # pokeElemOff :: Ptr HalideDimension -> Int -> HalideDimension -> IO () # peekByteOff :: Ptr b -> Int -> IO HalideDimension # pokeByteOff :: Ptr b -> Int -> HalideDimension -> IO () # peek :: Ptr HalideDimension -> IO HalideDimension # poke :: Ptr HalideDimension -> HalideDimension -> IO () # | |
Read HalideDimension Source # | |
Defined in Language.Halide.Buffer | |
Show HalideDimension Source # | |
Defined in Language.Halide.Buffer showsPrec :: Int -> HalideDimension -> ShowS # show :: HalideDimension -> String # showList :: [HalideDimension] -> ShowS # | |
Eq HalideDimension Source # | |
Defined in Language.Halide.Buffer (==) :: HalideDimension -> HalideDimension -> Bool # (/=) :: HalideDimension -> HalideDimension -> Bool # |
data HalideDeviceInterface Source #
Haskell analogue of halide_device_interface_t
.
:: Integral a | |
=> [a] | Extents |
-> [a] |
Get strides corresponding to row-major ordering
:: 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.
Instances
Specifies how loop values are traversed.
Instances
data SplitContents Source #
SplitContents | |
|
Instances
Show SplitContents Source # | |
Defined in Language.Halide.Schedule showsPrec :: Int -> SplitContents -> ShowS # show :: SplitContents -> String # showList :: [SplitContents] -> ShowS # |
data FuseContents Source #
Instances
Show FuseContents Source # | |
Defined in Language.Halide.Schedule showsPrec :: Int -> FuseContents -> ShowS # show :: FuseContents -> String # showList :: [FuseContents] -> ShowS # | |
Eq FuseContents Source # | |
Defined in Language.Halide.Schedule (==) :: FuseContents -> FuseContents -> Bool # (/=) :: FuseContents -> FuseContents -> Bool # |
Instances
data StorageDim Source #
StorageDim | |
|
Instances
Show StorageDim Source # | |
Defined in Language.Halide.Schedule 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 #
Instances
Show FuseLoopLevel Source # | |
Defined in Language.Halide.Schedule showsPrec :: Int -> FuseLoopLevel -> ShowS # show :: FuseLoopLevel -> String # showList :: [FuseLoopLevel] -> ShowS # | |
Eq FuseLoopLevel Source # | |
Defined in Language.Halide.Schedule (==) :: FuseLoopLevel -> FuseLoopLevel -> Bool # (/=) :: FuseLoopLevel -> FuseLoopLevel -> Bool # |
data StageSchedule Source #
StageSchedule | |
|
Instances
Show StageSchedule Source # | |
Defined in Language.Halide.Schedule showsPrec :: Int -> StageSchedule -> ShowS # show :: StageSchedule -> String # showList :: [StageSchedule] -> ShowS # |
data ReductionVariable Source #
Instances
Storable ReductionVariable Source # | |
Defined in Language.Halide.Schedule 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 showsPrec :: Int -> ReductionVariable -> ShowS # show :: ReductionVariable -> String # showList :: [ReductionVariable] -> ShowS # |
data PrefetchDirective Source #
PrefetchDirective | |
|
Instances
Storable PrefetchDirective Source # | |
Defined in Language.Halide.Schedule 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 showsPrec :: Int -> PrefetchDirective -> ShowS # show :: PrefetchDirective -> String # showList :: [PrefetchDirective] -> ShowS # |
getStageSchedule :: (KnownNat n, IsHalideType a) => Stage n a -> IO StageSchedule Source #
data AutoScheduler Source #
Instances
Show AutoScheduler Source # | |
Defined in Language.Halide.Schedule showsPrec :: Int -> AutoScheduler -> ShowS # show :: AutoScheduler -> String # showList :: [AutoScheduler] -> ShowS # | |
Eq AutoScheduler Source # | |
Defined in Language.Halide.Schedule (==) :: 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.
FunctionArguments (a -> b) = a ': FunctionArguments b | |
FunctionArguments a = '[] |
type family FunctionReturn (f :: Type) :: Type where ... Source #
Get the return type of a function.
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 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 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 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 |