halide-haskell-0.0.2.0: Haskell bindings to Halide
Copyright(c) Tom Westerhout 2023
Safe HaskellSafe-Inferred
LanguageGHC2021

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

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.

data Expr a Source #

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 IORef is initialized with Nothing and filled in on the first call to asExpr.

Instances

Instances details
HasField "extent" Dimension (Expr Int32) Source # 
Instance details

Defined in Language.Halide.Dimension

HasField "max" Dimension (Expr Int32) Source # 
Instance details

Defined in Language.Halide.Dimension

HasField "min" Dimension (Expr Int32) Source # 
Instance details

Defined in Language.Halide.Dimension

HasField "stride" Dimension (Expr Int32) Source # 
Instance details

Defined in Language.Halide.Dimension

HasField "var" (LoopLevel 'LockedTy) (Expr Int32) Source # 
Instance details

Defined in Language.Halide.LoopLevel

(IsHalideType a, Floating a) => Floating (Expr a) Source # 
Instance details

Defined in Language.Halide.Expr

Methods

pi :: Expr a Source #

exp :: Expr a -> Expr a Source #

log :: Expr a -> Expr a Source #

sqrt :: Expr a -> Expr a Source #

(**) :: Expr a -> Expr a -> Expr a Source #

logBase :: Expr a -> Expr a -> Expr a Source #

sin :: Expr a -> Expr a Source #

cos :: Expr a -> Expr a Source #

tan :: Expr a -> Expr a Source #

asin :: Expr a -> Expr a Source #

acos :: Expr a -> Expr a Source #

atan :: Expr a -> Expr a Source #

sinh :: Expr a -> Expr a Source #

cosh :: Expr a -> Expr a Source #

tanh :: Expr a -> Expr a Source #

asinh :: Expr a -> Expr a Source #

acosh :: Expr a -> Expr a Source #

atanh :: Expr a -> Expr a Source #

log1p :: Expr a -> Expr a Source #

expm1 :: Expr a -> Expr a Source #

log1pexp :: Expr a -> Expr a Source #

log1mexp :: Expr a -> Expr a Source #

(IsHalideType a, Num a) => Num (Expr a) Source # 
Instance details

Defined in Language.Halide.Expr

Methods

(+) :: Expr a -> Expr a -> Expr a Source #

(-) :: Expr a -> Expr a -> Expr a Source #

(*) :: Expr a -> Expr a -> Expr a Source #

negate :: Expr a -> Expr a Source #

abs :: Expr a -> Expr a Source #

signum :: Expr a -> Expr a Source #

fromInteger :: Integer -> Expr a Source #

(IsHalideType a, Fractional a) => Fractional (Expr a) Source # 
Instance details

Defined in Language.Halide.Expr

Methods

(/) :: Expr a -> Expr a -> Expr a Source #

recip :: Expr a -> Expr a Source #

fromRational :: Rational -> Expr a Source #

IsHalideType a => Show (Expr a) Source # 
Instance details

Defined in Language.Halide.Expr

Methods

showsPrec :: Int -> Expr a -> ShowS Source #

show :: Expr a -> String Source #

showList :: [Expr a] -> ShowS Source #

IsTuple '[Expr a1] (Expr a1) Source # 
Instance details

Defined in Language.Halide.Expr

Methods

toTuple :: Arguments '[Expr a1] -> Expr a1 Source #

fromTuple :: Expr a1 -> Arguments '[Expr a1] Source #

type VarOrRVar = Expr Int32 Source #

Either Var or RVar.

class Storable a => IsHalideType a Source #

Specifies that a type is supported by Halide.

Minimal complete definition

halideTypeFor, toCxxExpr

Instances

Instances details
IsHalideType CDouble Source # 
Instance details

Defined in Language.Halide.Expr

Methods

halideTypeFor :: proxy CDouble -> HalideType

toCxxExpr :: CDouble -> IO (ForeignPtr CxxExpr)

IsHalideType CFloat Source # 
Instance details

Defined in Language.Halide.Expr

Methods

halideTypeFor :: proxy CFloat -> HalideType

toCxxExpr :: CFloat -> IO (ForeignPtr CxxExpr)

IsHalideType Int16 Source # 
Instance details

Defined in Language.Halide.Expr

Methods

halideTypeFor :: proxy Int16 -> HalideType

toCxxExpr :: Int16 -> IO (ForeignPtr CxxExpr)

IsHalideType Int32 Source # 
Instance details

Defined in Language.Halide.Expr

Methods

halideTypeFor :: proxy Int32 -> HalideType

toCxxExpr :: Int32 -> IO (ForeignPtr CxxExpr)

IsHalideType Int64 Source # 
Instance details

Defined in Language.Halide.Expr

Methods

halideTypeFor :: proxy Int64 -> HalideType

toCxxExpr :: Int64 -> IO (ForeignPtr CxxExpr)

IsHalideType Int8 Source # 
Instance details

Defined in Language.Halide.Expr

Methods

halideTypeFor :: proxy Int8 -> HalideType

toCxxExpr :: Int8 -> IO (ForeignPtr CxxExpr)

IsHalideType Word16 Source # 
Instance details

Defined in Language.Halide.Expr

Methods

halideTypeFor :: proxy Word16 -> HalideType

toCxxExpr :: Word16 -> IO (ForeignPtr CxxExpr)

IsHalideType Word32 Source # 
Instance details

Defined in Language.Halide.Expr

Methods

halideTypeFor :: proxy Word32 -> HalideType

toCxxExpr :: Word32 -> IO (ForeignPtr CxxExpr)

IsHalideType Word64 Source # 
Instance details

Defined in Language.Halide.Expr

Methods

halideTypeFor :: proxy Word64 -> HalideType

toCxxExpr :: Word64 -> IO (ForeignPtr CxxExpr)

IsHalideType Word8 Source # 
Instance details

Defined in Language.Halide.Expr

Methods

halideTypeFor :: proxy Word8 -> HalideType

toCxxExpr :: Word8 -> IO (ForeignPtr CxxExpr)

IsHalideType Bool Source # 
Instance details

Defined in Language.Halide.Expr

Methods

halideTypeFor :: proxy Bool -> HalideType

toCxxExpr :: Bool -> IO (ForeignPtr CxxExpr)

IsHalideType Double Source # 
Instance details

Defined in Language.Halide.Expr

Methods

halideTypeFor :: proxy Double -> HalideType

toCxxExpr :: Double -> IO (ForeignPtr CxxExpr)

IsHalideType Float Source # 
Instance details

Defined in Language.Halide.Expr

Methods

halideTypeFor :: proxy Float -> HalideType

toCxxExpr :: Float -> IO (ForeignPtr CxxExpr)

data ReductionDomain (n :: Nat) Source #

An n-dimensional reduction domain.

Creating

mkExpr :: IsHalideType a => a -> Expr a Source #

Create a scalar expression from a Haskell value.

mkVar :: Text -> IO (Expr Int32) Source #

Create a named index variable.

mkRVar Source #

Arguments

:: Text

name

-> Expr Int32

min index

-> Expr Int32

extent

-> IO (Expr Int32) 

Create a named reduction variable.

For more information about reduction variables, see Halide::RDom.

mkRDom Source #

Arguments

:: forall n. HasIndexType n 
=> Text

name

-> IndexType n

mins

-> IndexType n

extents

-> IO (ReductionDomain n)

reduction variables

Create a reduction domain. Use asRVar to cast it into an index.

For more information about reduction variables, see Halide::RDom.

toRVars :: forall n. HasIndexType n => ReductionDomain n -> IO (IndexType n) Source #

Cast a reduction domain into a multi-dimensional index that can be used to perform multi-dimensional reductions.

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.

ifThenElse :: IsHalideType a => Expr Bool -> Expr a -> Expr a -> Expr a Source #

'ifThenElse cond a b' is the analogue of if cond then a else b, but lifted to work with Expr types.

See also the RebindableSyntax extension.

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 :: forall a t. (IsHalideType a, PrintedType t (Expr a)) => Expr a -> t Source #

Print all expressions to stdout when the result is evaluates. The first expression is returned.

This is useful for debugging Halide pipelines.

This function is similar to printf in that it accepts a variable number of arguments, i.e the following is valid:

let x :: Expr Float
    x = 1
 in printed (sin x) ("<- sin(" :: Text) x (")" :: Text)

:: Text specifications are only needed if you have the OverloadedStrings extension enabled.

Arguments to printed can be Expr a, String, or Text.

printedWhen :: forall a t. (IsHalideType a, PrintedType t (Expr a)) => Expr Bool -> Expr a -> t Source #

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.

eq :: IsHalideType a => Expr a -> Expr a -> Expr Bool infix 4 Source #

== but lifted to return an Expr.

neq :: IsHalideType a => Expr a -> Expr a -> Expr Bool infix 4 Source #

/= but lifted to return an Expr.

lt :: IsHalideType a => Expr a -> Expr a -> Expr Bool infix 4 Source #

< but lifted to return an Expr.

lte :: IsHalideType a => Expr a -> Expr a -> Expr Bool infix 4 Source #

<= but lifted to return an Expr.

gt :: IsHalideType a => Expr a -> Expr a -> Expr Bool infix 4 Source #

> but lifted to return an Expr.

gte :: IsHalideType a => Expr a -> Expr a -> Expr Bool infix 4 Source #

>= but lifted to return an Expr.

min :: IsHalideType a => Expr a -> Expr a -> Expr a Source #

min but lifted to return an Expr.

max :: IsHalideType a => Expr a -> Expr a -> Expr a Source #

max but lifted to return an Expr.

div :: forall a. (IsHalideType a, Integral a) => Expr a -> Expr a -> Expr a Source #

Divide two integers, rounding towards zero.

mod :: forall a. (IsHalideType a, Integral a) => Expr a -> Expr a -> Expr a Source #

Compute the remainder of dividing two integers, when division is rounding toward zero.

Boolean functions

and :: Expr Bool -> Expr Bool -> Expr Bool Source #

&& but lifted to return an Expr.

or :: Expr Bool -> Expr Bool -> Expr Bool Source #

|| but lifted to return an Expr.

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.

Here, a is most often Expr t for a type t that is an instance of IsHalideType. However, one can also define Funcs that return multiple values. In this case, a will be a tuple of Exprs.

This is a wrapper around the Halide::Func C++ type.

Constructors

Func :: !(ForeignPtr CxxFunc) -> Func 'FuncTy n a 
Param :: IsHalideType a => !(IORef (Maybe (ForeignPtr CxxImageParam))) -> Func 'ParamTy n (Expr a) 

Instances

Instances details
KnownNat n => Schedulable (Func t) n a Source # 
Instance details

Defined in Language.Halide.Func

Methods

vectorize :: VarOrRVar -> Func t n a -> IO (Func t n a) Source #

unroll :: VarOrRVar -> Func t n a -> IO (Func t n a) Source #

reorder :: [VarOrRVar] -> Func t n a -> IO (Func t n a) Source #

split :: TailStrategy -> VarOrRVar -> (VarOrRVar, VarOrRVar) -> Expr Int32 -> Func t n a -> IO (Func t n a) Source #

fuse :: (VarOrRVar, VarOrRVar) -> VarOrRVar -> Func t n a -> IO (Func t n a) Source #

serial :: VarOrRVar -> Func t n a -> IO (Func t n a) Source #

parallel :: VarOrRVar -> Func t n a -> IO (Func t n a) Source #

atomic :: Bool -> Func t n a -> IO (Func t n a) Source #

specialize :: Expr Bool -> Func t n a -> IO (Stage n a) Source #

specializeFail :: Text -> Func t n a -> IO () Source #

gpuBlocks :: forall (k :: Nat). (KnownNat k, 1 <= k, k <= 3) => DeviceAPI -> IndexType k -> Func t n a -> IO (Func t n a) Source #

gpuThreads :: forall (k :: Nat). (KnownNat k, 1 <= k, k <= 3) => DeviceAPI -> IndexType k -> Func t n a -> IO (Func t n a) Source #

gpuLanes :: DeviceAPI -> VarOrRVar -> Func t n a -> IO (Func t n a) Source #

computeWith :: forall (t0 :: LoopLevelTy). LoopAlignStrategy -> Func t n a -> LoopLevel t0 -> IO () Source #

type Function n a = Func 'FuncTy n (Expr a) Source #

Synonym for the most commonly used function type.

type Parameter n a = Func 'ParamTy n (Expr a) Source #

Synonym for the most commonly used parameter type.

data FuncTy Source #

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.

Constructors

FuncTy 
ParamTy 

Instances

Instances details
Show FuncTy Source # 
Instance details

Defined in Language.Halide.Func

Eq FuncTy Source # 
Instance details

Defined in Language.Halide.Func

Ord FuncTy Source # 
Instance details

Defined in Language.Halide.Func

newtype Stage (n :: Nat) (a :: Type) Source #

A single definition of a Func.

Constructors

Stage (ForeignPtr CxxStage) 

Instances

Instances details
KnownNat n => Schedulable Stage n a Source # 
Instance details

Defined in Language.Halide.Func

Methods

vectorize :: VarOrRVar -> Stage n a -> IO (Stage n a) Source #

unroll :: VarOrRVar -> Stage n a -> IO (Stage n a) Source #

reorder :: [VarOrRVar] -> Stage n a -> IO (Stage n a) Source #

split :: TailStrategy -> VarOrRVar -> (VarOrRVar, VarOrRVar) -> Expr Int32 -> Stage n a -> IO (Stage n a) Source #

fuse :: (VarOrRVar, VarOrRVar) -> VarOrRVar -> Stage n a -> IO (Stage n a) Source #

serial :: VarOrRVar -> Stage n a -> IO (Stage n a) Source #

parallel :: VarOrRVar -> Stage n a -> IO (Stage n a) Source #

atomic :: Bool -> Stage n a -> IO (Stage n a) Source #

specialize :: Expr Bool -> Stage n a -> IO (Stage n a) Source #

specializeFail :: Text -> Stage n a -> IO () Source #

gpuBlocks :: forall (k :: Nat). (KnownNat k, 1 <= k, k <= 3) => DeviceAPI -> IndexType k -> Stage n a -> IO (Stage n a) Source #

gpuThreads :: forall (k :: Nat). (KnownNat k, 1 <= k, k <= 3) => DeviceAPI -> IndexType k -> Stage n a -> IO (Stage n a) Source #

gpuLanes :: DeviceAPI -> VarOrRVar -> Stage n a -> IO (Stage n a) Source #

computeWith :: forall (t :: LoopLevelTy). LoopAlignStrategy -> Stage n a -> LoopLevel t -> IO () Source #

Creating

define :: forall n d. (HasIndexType n, IsFuncDefinition d) => Text -> IndexType n -> d -> IO (Func 'FuncTy n d) 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 :: forall n d. (HasIndexType n, IsFuncDefinition d) => Func 'FuncTy n d -> IndexType n -> d -> 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.

(!) :: (HasIndexType n, IsFuncDefinition a) => Func t n a -> IndexType n -> a infix 9 Source #

Apply a Halide function. Conceptually, f ! i is equivalent to f[i], i.e. indexing into a lazy array.

repeatEdge :: (KnownNat n, IsHalideType a) => Func 'ParamTy n (Expr a) -> IO (Func 'FuncTy n (Expr a)) Source #

Impose a boundary condition such that the nearest edge sample is returned everywhere outside the given region.

For more information, see Halide::repeat_edge.

constantExterior :: (KnownNat n, IsHalideType a) => Expr a -> Func 'ParamTy n (Expr a) -> IO (Func 'FuncTy n (Expr a)) Source #

Impose a boundary condition such that a given expression is returned everywhere outside the boundary.

For more information, see Halide::constant_exterior.

Inspecting

getArgs :: KnownNat n => Func t n a -> IO [Var] Source #

Get the index arguments of the function.

The returned list contains exactly n elements.

hasUpdateDefinitions :: KnownNat n => Func t n a -> IO Bool Source #

Return True when the function has update definitions, False otherwise.

getUpdateStage :: KnownNat n => 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 Ptr (HalideBuffer n a) for input and output array arguments.

Instances

Instances details
Show (HalideBuffer n a) Source # 
Instance details

Defined in Language.Halide.Buffer

Eq (HalideBuffer n a) Source # 
Instance details

Defined in Language.Halide.Buffer

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 =<< peekToList out  -- print it for debugging

allocaBuffer :: forall n a b. (HasCallStack, KnownNat n, IsHalideType a) => Target -> [Int] -> (Ptr (HalideBuffer n a) -> IO b) -> IO b Source #

Buffers can also be converted to lists to easily print them for debugging.

class (KnownNat n, IsHalideType a, NestedList n a ~ b, NestedListLevel b ~ n, NestedListType b ~ a) => IsListPeek n a b | n a -> b, n b -> a, a b -> n where Source #

Instances

Instances details
(IsHalideType a, NestedListLevel [a] ~ 1, NestedListType [a] ~ a) => IsListPeek 1 a [a] Source # 
Instance details

Defined in Language.Halide.Buffer

Methods

peekToList :: Ptr (HalideBuffer 1 a) -> IO [a] Source #

(IsHalideType a, NestedListLevel [[a]] ~ 2, NestedListType [[a]] ~ a) => IsListPeek 2 a [[a]] Source # 
Instance details

Defined in Language.Halide.Buffer

Methods

peekToList :: Ptr (HalideBuffer 2 a) -> IO [[a]] Source #

(IsHalideType a, NestedListLevel [[[a]]] ~ 3, NestedListType [[[a]]] ~ a) => IsListPeek 3 a [[[a]]] Source # 
Instance details

Defined in Language.Halide.Buffer

Methods

peekToList :: Ptr (HalideBuffer 3 a) -> IO [[[a]]] Source #

(IsHalideType a, NestedListLevel [[[[a]]]] ~ 4, NestedListType [[[[a]]]] ~ a) => IsListPeek 4 a [[[[a]]]] Source # 
Instance details

Defined in Language.Halide.Buffer

Methods

peekToList :: Ptr (HalideBuffer 4 a) -> IO [[[[a]]]] Source #

peekScalar :: forall a. (HasCallStack, IsHalideType a) => Ptr (HalideBuffer 0 a) -> IO 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

Instances details
IsHalideType a => IsHalideBuffer (Vector a) 1 a Source #

Storable vectors are one-dimensional buffers. This involves no copying.

Instance details

Defined in Language.Halide.Buffer

Methods

withHalideBufferImpl :: Vector a -> (Ptr (HalideBuffer 1 a) -> IO b) -> IO b Source #

IsHalideType a => IsHalideBuffer [[[[a]]]] 4 a Source #

Lists can also act as Halide buffers. Use for testing only.

Instance details

Defined in Language.Halide.Buffer

Methods

withHalideBufferImpl :: [[[[a]]]] -> (Ptr (HalideBuffer 4 a) -> IO b) -> IO b Source #

IsHalideType a => IsHalideBuffer [[[a]]] 3 a Source #

Lists can also act as Halide buffers. Use for testing only.

Instance details

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.

Instance details

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.

Instance details

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.

Instance details

Defined in Language.Halide.Buffer

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.

bufferFromPtrShape Source #

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.

realize Source #

Arguments

:: forall n a t b. (KnownNat n, IsHalideType a) 
=> Func t n (Expr 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 

Similar to realizeOnTarget except that the pipeline is run on hostTarget.

realizeOnTarget Source #

Arguments

:: forall n a t b. (KnownNat n, IsHalideType a) 
=> Target

Target on which to run the pipeline

-> Func t n (Expr 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.

If your target is a GPU, this function will not automatically copy data back from the GPU.

asBufferParam Source #

Arguments

:: forall n a t b. IsHalideBuffer t n a 
=> t

Object to treat as a buffer

-> (Func 'ParamTy n (Expr 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 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 HalideBuffers instead of Funcs.

compile Source #

Arguments

:: forall f n a. (FuncBuilder f n a, IsHalideKernel (LoweredSignature f)) 
=> f

Function to compile

-> IO (LoweredSignature f)

Compiled kernel

Specifies how Expr and Func parameters become scalar and buffer arguments in compiled kernels. type family Lowered (t :: k) :: k where Lowered (Expr a) = a Lowered (Func t n (Expr a)) = Ptr (HalideBuffer n a) Lowered '[] = '[] Lowered (t ': ts) = (Lowered t ': Lowered ts)

A constraint that specifies that the function f returns IO (Func t n a). class (FunctionReturn f ~ IO (Func 'FuncTy n a), KnownNat n) => ReturnsFunc f n a | f -> n a

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 <- compile builder
withHalideBuffer 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 (Expr a) -> Func 'ParamTy n (Expr 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:

newtype Dimension Source #

Information about a buffer's dimension, such as the min, extent, and stride.

Instances

Instances details
Show Dimension Source # 
Instance details

Defined in Language.Halide.Dimension

HasField "extent" Dimension (Expr Int32) Source # 
Instance details

Defined in Language.Halide.Dimension

HasField "max" Dimension (Expr Int32) Source # 
Instance details

Defined in Language.Halide.Dimension

HasField "min" Dimension (Expr Int32) Source # 
Instance details

Defined in Language.Halide.Dimension

HasField "stride" Dimension (Expr Int32) Source # 
Instance details

Defined in Language.Halide.Dimension

dim :: forall n a. (HasCallStack, KnownNat n) => Int -> Func 'ParamTy n (Expr 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.

setEstimate Source #

Arguments

:: Expr Int32

min estimate

-> Expr Int32

extent estimate

-> Dimension 
-> IO Dimension 

Set estimates for autoschedulers.

setScalarEstimate Source #

Arguments

:: IsHalideType a 
=> a

Estimate

-> Expr a

Parameter

-> IO () 

Targets

newtype Target Source #

The compilation target.

This is the Haskell counterpart of Halide::Target.

Constructors

Target (ForeignPtr CxxTarget) 

Instances

Instances details
Show Target Source # 
Instance details

Defined in Language.Halide.Target

Eq Target Source # 
Instance details

Defined in Language.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 f n a. (FuncBuilder f n a, IsHalideKernel (LoweredSignature f)) => Target -> f -> IO (LoweredSignature f) Source #

Similar to compile, but the first argument lets you explicitly specify the compilation target.

data DeviceAPI Source #

An enum describing the type of device API.

This is the Haskell counterpart of Halide::DeviceAPI.

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

setFeature Source #

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 #

Arguments

:: Target 
-> Bool

Whether the target appears to be usable

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 => Schedulable f (n :: Nat) (a :: Type) 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 Source #

Arguments

:: [VarOrRVar]

variables

-> f n a

function or stage

-> IO (f n a) 

Reorder variables to have the given nesting order, from innermost out.

Note that variables should only contain variables that belong to the function. If this is not the case, a runtime error will be thrown.

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

atomic Source #

Arguments

:: Bool

whether to override the associativity test

-> f n a 
-> IO (f n a) 

Issue atomic updates for this Func.

specialize :: Expr Bool -> f n a -> IO (Stage n a) Source #

specializeFail :: Text -> f n a -> IO () Source #

gpuBlocks :: (KnownNat k, 1 <= k, k <= 3) => DeviceAPI -> IndexType k -> f n a -> IO (f n a) Source #

gpuThreads :: (KnownNat k, 1 <= k, k <= 3) => DeviceAPI -> IndexType k -> 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

Instances details
KnownNat n => Schedulable Stage n a Source # 
Instance details

Defined in Language.Halide.Func

Methods

vectorize :: VarOrRVar -> Stage n a -> IO (Stage n a) Source #

unroll :: VarOrRVar -> Stage n a -> IO (Stage n a) Source #

reorder :: [VarOrRVar] -> Stage n a -> IO (Stage n a) Source #

split :: TailStrategy -> VarOrRVar -> (VarOrRVar, VarOrRVar) -> Expr Int32 -> Stage n a -> IO (Stage n a) Source #

fuse :: (VarOrRVar, VarOrRVar) -> VarOrRVar -> Stage n a -> IO (Stage n a) Source #

serial :: VarOrRVar -> Stage n a -> IO (Stage n a) Source #

parallel :: VarOrRVar -> Stage n a -> IO (Stage n a) Source #

atomic :: Bool -> Stage n a -> IO (Stage n a) Source #

specialize :: Expr Bool -> Stage n a -> IO (Stage n a) Source #

specializeFail :: Text -> Stage n a -> IO () Source #

gpuBlocks :: forall (k :: Nat). (KnownNat k, 1 <= k, k <= 3) => DeviceAPI -> IndexType k -> Stage n a -> IO (Stage n a) Source #

gpuThreads :: forall (k :: Nat). (KnownNat k, 1 <= k, k <= 3) => DeviceAPI -> IndexType k -> Stage n a -> IO (Stage n a) Source #

gpuLanes :: DeviceAPI -> VarOrRVar -> Stage n a -> IO (Stage n a) Source #

computeWith :: forall (t :: LoopLevelTy). LoopAlignStrategy -> Stage n a -> LoopLevel t -> IO () Source #

KnownNat n => Schedulable (Func t) n a Source # 
Instance details

Defined in Language.Halide.Func

Methods

vectorize :: VarOrRVar -> Func t n a -> IO (Func t n a) Source #

unroll :: VarOrRVar -> Func t n a -> IO (Func t n a) Source #

reorder :: [VarOrRVar] -> Func t n a -> IO (Func t n a) Source #

split :: TailStrategy -> VarOrRVar -> (VarOrRVar, VarOrRVar) -> Expr Int32 -> Func t n a -> IO (Func t n a) Source #

fuse :: (VarOrRVar, VarOrRVar) -> VarOrRVar -> Func t n a -> IO (Func t n a) Source #

serial :: VarOrRVar -> Func t n a -> IO (Func t n a) Source #

parallel :: VarOrRVar -> Func t n a -> IO (Func t n a) Source #

atomic :: Bool -> Func t n a -> IO (Func t n a) Source #

specialize :: Expr Bool -> Func t n a -> IO (Stage n a) Source #

specializeFail :: Text -> Func t n a -> IO () Source #

gpuBlocks :: forall (k :: Nat). (KnownNat k, 1 <= k, k <= 3) => DeviceAPI -> IndexType k -> Func t n a -> IO (Func t n a) Source #

gpuThreads :: forall (k :: Nat). (KnownNat k, 1 <= k, k <= 3) => DeviceAPI -> IndexType k -> Func t n a -> IO (Func t n a) Source #

gpuLanes :: DeviceAPI -> VarOrRVar -> Func t n a -> IO (Func t n a) Source #

computeWith :: forall (t0 :: LoopLevelTy). LoopAlignStrategy -> Func t n a -> LoopLevel t0 -> IO () Source #

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.

  • Pros: generates the simplest, fastest code.
  • Cons: if used on a stage that reads from the input or writes to the output, constrains the input or output size to be a multiple of the split factor.
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.

  • Pros: no redundant re-evaluation; does not constrain input our output sizes.
  • Cons: increases code size due to separate tail-case handling; vectorization will scalarize in the tail case to handle the if statement.
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 TailRoundUp, it supports vectorization well, because the inner loop is always a fixed size with no data-dependent branching. It increases code size slightly for inner loops due to the epilogue handling, but not for outer loops (e.g. loops over tiles). If used on a stage that reads from an input or writes to an output, this stategy only requires that the input/output extent be at least the split factor, instead of a multiple of the split factor as with TailRoundUp.

TailAuto

For pure definitions use TailShiftInwards.

For pure vars in update definitions use TailRoundUp. For RVars in update definitions use TailGuardWithIf.

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.

Instances

Instances details
HasField "func" (LoopLevel 'LockedTy) Text Source # 
Instance details

Defined in Language.Halide.LoopLevel

HasField "var" (LoopLevel 'LockedTy) (Expr Int32) Source # 
Instance details

Defined in Language.Halide.LoopLevel

Show (LoopLevel t) Source # 
Instance details

Defined in Language.Halide.LoopLevel

Eq (LoopLevel t) Source # 
Instance details

Defined in Language.Halide.LoopLevel

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

computeWith will make no attempt to align the start/end of the fused loops.

LoopAlignAuto

By default, LoopAlignStrategy is set to LoopNoAlign.

Instances

Instances details
Enum LoopAlignStrategy Source # 
Instance details

Defined in Language.Halide.LoopLevel

Show LoopAlignStrategy Source # 
Instance details

Defined in Language.Halide.LoopLevel

Eq LoopAlignStrategy Source # 
Instance details

Defined in Language.Halide.LoopLevel

Ord LoopAlignStrategy Source # 
Instance details

Defined in Language.Halide.LoopLevel

computeRoot :: KnownNat n => 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 => 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 => Func t n a -> Expr Int32 -> IO (LoopLevel 'LockedTy) Source #

Same as getLoopLevelAtStage except that the stage is -1.

getLoopLevelAtStage Source #

Arguments

:: KnownNat n 
=> 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 => 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) => 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 => 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 => Func t n a -> IO (Func t n a) Source #

storeAt :: KnownNat n => 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 => 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.

estimate Source #

Arguments

:: KnownNat n 
=> Expr Int32

index variable

-> Expr Int32

min estimate

-> Expr Int32

extent estimate

-> Func t n a 
-> IO () 

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.

bound Source #

Arguments

:: KnownNat n 
=> Expr Int32

index variable

-> Expr Int32

min estimate

-> Expr Int32

extent estimate

-> 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 => Func t n r -> IO Text Source #

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 f. FuncBuilder f 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 TraceEventCode Source #

Haskell counterpart of halide_trace_event_code_t.

Instances

Instances details
Enum TraceEventCode Source # 
Instance details

Defined in Language.Halide.Trace

Show TraceEventCode Source # 
Instance details

Defined in Language.Halide.Trace

Eq TraceEventCode Source # 
Instance details

Defined in Language.Halide.Trace

Ord TraceEventCode Source # 
Instance details

Defined in Language.Halide.Trace

setCustomTrace Source #

Arguments

:: KnownNat n 
=> (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 => Func t n a -> IO (Func t n a) Source #

traceLoads :: KnownNat n => Func t n a -> IO (Func t n a) Source #

collectIterationOrder :: KnownNat n => (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.

Methods

toTuple :: Arguments a -> t Source #

fromTuple :: t -> Arguments a Source #

Instances

Instances details
IsTuple ('[] :: [Type]) () Source # 
Instance details

Defined in Language.Halide.Expr

Methods

toTuple :: Arguments '[] -> () Source #

fromTuple :: () -> Arguments '[] Source #

IsTuple '[Expr a1] (Expr a1) Source # 
Instance details

Defined in Language.Halide.Expr

Methods

toTuple :: Arguments '[Expr a1] -> Expr a1 Source #

fromTuple :: Expr a1 -> Arguments '[Expr a1] Source #

IsTuple '[a1, a2] (a1, a2) Source # 
Instance details

Defined in Language.Halide.Expr

Methods

toTuple :: Arguments '[a1, a2] -> (a1, a2) Source #

fromTuple :: (a1, a2) -> Arguments '[a1, a2] Source #

IsTuple '[a1, a2, a3] (a1, a2, a3) Source # 
Instance details

Defined in Language.Halide.Expr

Methods

toTuple :: Arguments '[a1, a2, a3] -> (a1, a2, a3) Source #

fromTuple :: (a1, a2, a3) -> Arguments '[a1, a2, a3] Source #

IsTuple '[a1, a2, a3, a4] (a1, a2, a3, a4) Source # 
Instance details

Defined in Language.Halide.Expr

Methods

toTuple :: Arguments '[a1, a2, a3, a4] -> (a1, a2, a3, a4) Source #

fromTuple :: (a1, a2, a3, a4) -> Arguments '[a1, a2, a3, a4] Source #

IsTuple '[a1, a2, a3, a4, a5] (a1, a2, a3, a4, a5) Source # 
Instance details

Defined in Language.Halide.Expr

Methods

toTuple :: Arguments '[a1, a2, a3, a4, a5] -> (a1, a2, a3, a4, a5) Source #

fromTuple :: (a1, a2, a3, a4, a5) -> Arguments '[a1, a2, a3, a4, a5] Source #

IsTuple '[a1, a2, a3, a4, a5, a6] (a1, a2, a3, a4, a5, a6) Source # 
Instance details

Defined in Language.Halide.Expr

Methods

toTuple :: Arguments '[a1, a2, a3, a4, a5, a6] -> (a1, a2, a3, a4, a5, a6) Source #

fromTuple :: (a1, a2, a3, a4, a5, a6) -> Arguments '[a1, a2, a3, a4, a5, a6] Source #

IsTuple '[a1, a2, a3, a4, a5, a6, a7] (a1, a2, a3, a4, a5, a6, a7) Source # 
Instance details

Defined in Language.Halide.Expr

Methods

toTuple :: Arguments '[a1, a2, a3, a4, a5, a6, a7] -> (a1, a2, a3, a4, a5, a6, a7) Source #

fromTuple :: (a1, a2, a3, a4, a5, a6, a7) -> Arguments '[a1, a2, a3, a4, a5, a6, a7] Source #

IsTuple '[a1, a2, a3, a4, a5, a6, a7, a8] (a1, a2, a3, a4, a5, a6, a7, a8) Source # 
Instance details

Defined in Language.Halide.Expr

Methods

toTuple :: Arguments '[a1, a2, a3, a4, a5, a6, a7, a8] -> (a1, a2, a3, a4, a5, a6, a7, a8) Source #

fromTuple :: (a1, a2, a3, a4, a5, a6, a7, a8) -> Arguments '[a1, a2, a3, a4, a5, a6, a7, a8] Source #

IsTuple '[a1, a2, a3, a4, a5, a6, a7, a8, a9] (a1, a2, a3, a4, a5, a6, a7, a8, a9) Source # 
Instance details

Defined in Language.Halide.Expr

Methods

toTuple :: Arguments '[a1, a2, a3, a4, a5, a6, a7, a8, a9] -> (a1, a2, a3, a4, a5, a6, a7, a8, a9) Source #

fromTuple :: (a1, a2, a3, a4, a5, a6, a7, a8, a9) -> Arguments '[a1, a2, a3, a4, a5, a6, a7, a8, a9] Source #

IsTuple '[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10] (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) Source # 
Instance details

Defined in Language.Halide.Expr

Methods

toTuple :: Arguments '[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10] -> (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) Source #

fromTuple :: (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) -> Arguments '[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10] Source #

type family ToTuple t = s | s -> t where ... Source #

Type family that maps Arguments ts to the corresponding tuple type.

Equations

ToTuple '[] = () 
ToTuple '[Expr a1] = Expr a1 
ToTuple '[a1, a2] = (a1, a2) 
ToTuple '[a1, a2, a3] = (a1, a2, a3) 
ToTuple '[a1, a2, a3, a4] = (a1, a2, a3, a4) 
ToTuple '[a1, a2, a3, a4, a5] = (a1, a2, a3, a4, a5) 
ToTuple '[a1, a2, a3, a4, a5, a6] = (a1, a2, a3, a4, a5, a6) 
ToTuple '[a1, a2, a3, a4, a5, a6, a7] = (a1, a2, a3, a4, a5, a6, a7) 
ToTuple '[a1, a2, a3, a4, a5, a6, a7, a8] = (a1, a2, a3, a4, a5, a6, a7, a8) 
ToTuple '[a1, a2, a3, a4, a5, a6, a7, a8, a9] = (a1, a2, a3, a4, a5, a6, a7, a8, a9) 
ToTuple '[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10] = (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) 

type family FromTuple t = s | s -> t where ... Source #

Type family that maps tuples to the corresponding Arguments ts type. This is essentially the inverse of ToTuple.

Equations

FromTuple () = '[] 
FromTuple (Expr a1) = '[Expr a1] 
FromTuple (a1, a2) = '[a1, a2] 
FromTuple (a1, a2, a3) = '[a1, a2, a3] 
FromTuple (a1, a2, a3, a4) = '[a1, a2, a3, a4] 
FromTuple (a1, a2, a3, a4, a5) = '[a1, a2, a3, a4, a5] 
FromTuple (a1, a2, a3, a4, a5, a6) = '[a1, a2, a3, a4, a5, a6] 
FromTuple (a1, a2, a3, a4, a5, a6, a7) = '[a1, a2, a3, a4, a5, a6, a7] 
FromTuple (a1, a2, a3, a4, a5, a6, a7, a8) = '[a1, a2, a3, a4, a5, a6, a7, a8] 
FromTuple (a1, a2, a3, a4, a5, a6, a7, a8, a9) = '[a1, a2, a3, a4, a5, a6, a7, a8, a9] 
FromTuple (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) = '[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10] 

type family Length (xs :: [k]) :: Nat where ... Source #

A type family that returns the length of a type-level list.

Equations

Length '[] = 0 
Length (x ': xs) = 1 + Length xs 

type family All (c :: Type -> Constraint) (ts :: [Type]) = (p :: Constraint) | p -> ts where ... Source #

Apply constraint to all types in a list.

Equations

All c '[] = () 
All c (t ': ts) = (c t, All c ts) 

Internal

compileToCallable :: forall n a f. (FuncBuilder f n a, IsHalideKernel (LoweredSignature f)) => Target -> f -> IO (Callable (LoweredSignature f)) Source #

testCUDA :: IO () 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 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

data HalideDimension Source #

Information about a dimension in a buffer.

It is the Haskell analogue of halide_dimension_t.

Constructors

HalideDimension 

Fields

rowMajorStrides Source #

Arguments

:: Integral a 
=> [a]

Extents

-> [a] 

Get strides corresponding to row-major ordering

colMajorStrides Source #

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?

getBufferExtent :: forall n a. KnownNat n => Ptr (HalideBuffer n a) -> Int -> IO Int Source #

bufferCopyToHost :: HasCallStack => Ptr RawHalideBuffer -> IO () Source #

Copy the underlying memory from device to host.

withCopiedToHost :: Ptr (HalideBuffer n a) -> IO b -> IO b Source #

withCopiedToHost buf action performs the action action ensuring that buf has been copied to the host beforehand. If buf is already on the host, no copying is performed.

withCropped Source #

Arguments

:: Ptr (HalideBuffer n a)

buffer

-> Int

dimension

-> Int

min

-> Int

extent

-> (Ptr (HalideBuffer n a) -> IO b)

what to do

-> IO b 

Perform an action on a cropped buffer.

data Dim Source #

Constructors

Dim 

Instances

Instances details
Storable Dim Source # 
Instance details

Defined in Language.Halide.Schedule

Show Dim Source # 
Instance details

Defined in Language.Halide.Schedule

Eq Dim Source # 
Instance details

Defined in Language.Halide.Schedule

Methods

(==) :: Dim -> Dim -> Bool Source #

(/=) :: Dim -> Dim -> Bool Source #

data DimType Source #

Type of dimension that tells which transformations are legal on it.

data Split Source #

Instances

Instances details
Storable Split Source # 
Instance details

Defined in Language.Halide.Schedule

Show Split Source # 
Instance details

Defined in Language.Halide.Schedule

data Bound Source #

Constructors

Bound 

Instances

Instances details
Show Bound Source # 
Instance details

Defined in Language.Halide.Schedule

data StorageDim Source #

Instances

Instances details
Show StorageDim Source # 
Instance details

Defined in Language.Halide.Schedule

applySplits :: KnownNat n => [Split] -> Stage n a -> IO () Source #

applyDims :: KnownNat n => [Dim] -> Stage n a -> IO () Source #

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.

Methods

curryG :: (Arguments args -> r) -> f Source #

Instances

Instances details
Curry ('[] :: [Type]) r r Source # 
Instance details

Defined in Language.Halide.Type

Methods

curryG :: (Arguments '[] -> r) -> r Source #

Curry args r f => Curry (a ': args) r (a -> f) Source # 
Instance details

Defined in Language.Halide.Type

Methods

curryG :: (Arguments (a ': args) -> r) -> a -> f Source #

class UnCurry (f :: Type) (args :: [Type]) (r :: Type) | args r -> f, args f -> r 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.

Methods

uncurryG :: f -> Arguments args -> r Source #

Instances

Instances details
(FunctionArguments f ~ ('[] :: [Type]), FunctionReturn f ~ r, f ~ r) => UnCurry f ('[] :: [Type]) r Source # 
Instance details

Defined in Language.Halide.Type

Methods

uncurryG :: f -> Arguments '[] -> r Source #

UnCurry f args r => UnCurry (a -> f) (a ': args) r Source # 
Instance details

Defined in Language.Halide.Type

Methods

uncurryG :: (a -> f) -> Arguments (a ': args) -> r Source #

type family LoweredSignature f where ... Source #

Equations

LoweredSignature (Expr a -> r) = a -> LoweredSignature r 
LoweredSignature (Func t n (Expr a) -> r) = Ptr (HalideBuffer n a) -> LoweredSignature r 
LoweredSignature (IO (Func t n (Expr a))) = Ptr (HalideBuffer n a) -> IO () 
LoweredSignature (IO (Func t n (Expr a1, Expr a2))) = Ptr (HalideBuffer n a1) -> Ptr (HalideBuffer n a2) -> IO () 

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 CxxExpr Source #

Haskell counterpart of Halide::Expr.

data CxxVar Source #

Haskell counterpart of Halide::Var.

data CxxRVar Source #

Haskell counterpart of Halide::RVar.

data CxxParameter Source #

Haskell counterpart of Halide::Internal::Parameter.

data CxxFunc Source #

Haskell counterpart of Halide::Func.

data CxxImageParam Source #

Haskell counterpart of Halide::ImageParam.

data CxxStage Source #

Haskell counterpart of Halide::Stage.

data CxxDimension Source #

Haskell counterpart of Halide::Internal::Dimension.

data CxxTarget Source #

Haskell counterpart of Halide::Target.

data CxxLoopLevel Source #

Haskell counterpart of Halide::LoopLevel

Convenience re-exports

data Int32 Source #

32-bit signed integer type

Instances

Instances details
Storable Int32

Since: base-2.1

Instance details

Defined in Foreign.Storable

Bits Int32

Since: base-2.1

Instance details

Defined in GHC.Int

FiniteBits Int32

Since: base-4.6.0.0

Instance details

Defined in GHC.Int

Bounded Int32

Since: base-2.1

Instance details

Defined in GHC.Int

Enum Int32

Since: base-2.1

Instance details

Defined in GHC.Int

Ix Int32

Since: base-2.1

Instance details

Defined in GHC.Int

Num Int32

Since: base-2.1

Instance details

Defined in GHC.Int

Read Int32

Since: base-2.1

Instance details

Defined in GHC.Int

Integral Int32

Since: base-2.1

Instance details

Defined in GHC.Int

Real Int32

Since: base-2.1

Instance details

Defined in GHC.Int

Show Int32

Since: base-2.1

Instance details

Defined in GHC.Int

Eq Int32

Since: base-2.1

Instance details

Defined in GHC.Int

Methods

(==) :: Int32 -> Int32 -> Bool Source #

(/=) :: Int32 -> Int32 -> Bool Source #

Ord Int32

Since: base-2.1

Instance details

Defined in GHC.Int

IsHalideType Int32 Source # 
Instance details

Defined in Language.Halide.Expr

Methods

halideTypeFor :: proxy Int32 -> HalideType

toCxxExpr :: Int32 -> IO (ForeignPtr CxxExpr)

Hashable Int32 
Instance details

Defined in Data.Hashable.Class

Prim Int32 
Instance details

Defined in Data.Primitive.Types

Uniform Int32 
Instance details

Defined in System.Random.Internal

Methods

uniformM :: StatefulGen g m => g -> m Int32 Source #

UniformRange Int32 
Instance details

Defined in System.Random.Internal

Methods

uniformRM :: StatefulGen g m => (Int32, Int32) -> g -> m Int32 Source #

Lift Int32 
Instance details

Defined in Language.Haskell.TH.Syntax

Methods

lift :: Quote m => Int32 -> m Exp Source #

liftTyped :: forall (m :: Type -> Type). Quote m => Int32 -> Code m Int32 Source #

HasField "extent" Dimension (Expr Int32) Source # 
Instance details

Defined in Language.Halide.Dimension

HasField "max" Dimension (Expr Int32) Source # 
Instance details

Defined in Language.Halide.Dimension

HasField "min" Dimension (Expr Int32) Source # 
Instance details

Defined in Language.Halide.Dimension

HasField "stride" Dimension (Expr Int32) Source # 
Instance details

Defined in Language.Halide.Dimension

HasField "var" (LoopLevel 'LockedTy) (Expr Int32) Source # 
Instance details

Defined in Language.Halide.LoopLevel

data Ptr a Source #

A value of type Ptr a represents a pointer to an object, or an array of objects, which may be marshalled to or from Haskell values of type a.

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

Instances details
Generic1 (URec (Ptr ()) :: k -> Type) 
Instance details

Defined in GHC.Generics

Associated Types

type Rep1 (URec (Ptr ())) :: k -> Type Source #

Methods

from1 :: forall (a :: k0). URec (Ptr ()) a -> Rep1 (URec (Ptr ())) a Source #

to1 :: forall (a :: k0). Rep1 (URec (Ptr ())) a -> URec (Ptr ()) a Source #

Foldable (UAddr :: TYPE LiftedRep -> Type)

Since: base-4.9.0.0

Instance details

Defined in Data.Foldable

Methods

fold :: Monoid m => UAddr m -> m Source #

foldMap :: Monoid m => (a -> m) -> UAddr a -> m Source #

foldMap' :: Monoid m => (a -> m) -> UAddr a -> m Source #

foldr :: (a -> b -> b) -> b -> UAddr a -> b Source #

foldr' :: (a -> b -> b) -> b -> UAddr a -> b Source #

foldl :: (b -> a -> b) -> b -> UAddr a -> b Source #

foldl' :: (b -> a -> b) -> b -> UAddr a -> b Source #

foldr1 :: (a -> a -> a) -> UAddr a -> a Source #

foldl1 :: (a -> a -> a) -> UAddr a -> a Source #

toList :: UAddr a -> [a] Source #

null :: UAddr a -> Bool Source #

length :: UAddr a -> Int Source #

elem :: Eq a => a -> UAddr a -> Bool Source #

maximum :: Ord a => UAddr a -> a Source #

minimum :: Ord a => UAddr a -> a Source #

sum :: Num a => UAddr a -> a Source #

product :: Num a => UAddr a -> a Source #

Traversable (UAddr :: Type -> Type)

Since: base-4.9.0.0

Instance details

Defined in Data.Traversable

Methods

traverse :: Applicative f => (a -> f b) -> UAddr a -> f (UAddr b) Source #

sequenceA :: Applicative f => UAddr (f a) -> f (UAddr a) Source #

mapM :: Monad m => (a -> m b) -> UAddr a -> m (UAddr b) Source #

sequence :: Monad m => UAddr (m a) -> m (UAddr a) Source #

Storable (Ptr a)

Since: base-2.1

Instance details

Defined in Foreign.Storable

Methods

sizeOf :: Ptr a -> Int Source #

alignment :: Ptr a -> Int Source #

peekElemOff :: Ptr (Ptr a) -> Int -> IO (Ptr a) Source #

pokeElemOff :: Ptr (Ptr a) -> Int -> Ptr a -> IO () Source #

peekByteOff :: Ptr b -> Int -> IO (Ptr a) Source #

pokeByteOff :: Ptr b -> Int -> Ptr a -> IO () Source #

peek :: Ptr (Ptr a) -> IO (Ptr a) Source #

poke :: Ptr (Ptr a) -> Ptr a -> IO () Source #

Show (Ptr a)

Since: base-2.1

Instance details

Defined in GHC.Ptr

Methods

showsPrec :: Int -> Ptr a -> ShowS Source #

show :: Ptr a -> String Source #

showList :: [Ptr a] -> ShowS Source #

Eq (Ptr a)

Since: base-2.1

Instance details

Defined in GHC.Ptr

Methods

(==) :: Ptr a -> Ptr a -> Bool Source #

(/=) :: Ptr a -> Ptr a -> Bool Source #

Ord (Ptr a)

Since: base-2.1

Instance details

Defined in GHC.Ptr

Methods

compare :: Ptr a -> Ptr a -> Ordering Source #

(<) :: Ptr a -> Ptr a -> Bool Source #

(<=) :: Ptr a -> Ptr a -> Bool Source #

(>) :: Ptr a -> Ptr a -> Bool Source #

(>=) :: Ptr a -> Ptr a -> Bool Source #

max :: Ptr a -> Ptr a -> Ptr a Source #

min :: Ptr a -> Ptr a -> Ptr a Source #

Hashable (Ptr a) 
Instance details

Defined in Data.Hashable.Class

Methods

hashWithSalt :: Int -> Ptr a -> Int Source #

hash :: Ptr a -> Int Source #

Prim (Ptr a) 
Instance details

Defined in Data.Primitive.Types

Functor (URec (Ptr ()) :: TYPE LiftedRep -> Type)

Since: base-4.9.0.0

Instance details

Defined in GHC.Generics

Methods

fmap :: (a -> b) -> URec (Ptr ()) a -> URec (Ptr ()) b Source #

(<$) :: a -> URec (Ptr ()) b -> URec (Ptr ()) a Source #

Generic (URec (Ptr ()) p) 
Instance details

Defined in GHC.Generics

Associated Types

type Rep (URec (Ptr ()) p) :: Type -> Type Source #

Methods

from :: URec (Ptr ()) p -> Rep (URec (Ptr ()) p) x Source #

to :: Rep (URec (Ptr ()) p) x -> URec (Ptr ()) p Source #

Eq (URec (Ptr ()) p)

Since: base-4.9.0.0

Instance details

Defined in GHC.Generics

Methods

(==) :: URec (Ptr ()) p -> URec (Ptr ()) p -> Bool Source #

(/=) :: URec (Ptr ()) p -> URec (Ptr ()) p -> Bool Source #

Ord (URec (Ptr ()) p)

Since: base-4.9.0.0

Instance details

Defined in GHC.Generics

Methods

compare :: URec (Ptr ()) p -> URec (Ptr ()) p -> Ordering Source #

(<) :: URec (Ptr ()) p -> URec (Ptr ()) p -> Bool Source #

(<=) :: URec (Ptr ()) p -> URec (Ptr ()) p -> Bool Source #

(>) :: URec (Ptr ()) p -> URec (Ptr ()) p -> Bool Source #

(>=) :: URec (Ptr ()) p -> URec (Ptr ()) p -> Bool Source #

max :: URec (Ptr ()) p -> URec (Ptr ()) p -> URec (Ptr ()) p Source #

min :: URec (Ptr ()) p -> URec (Ptr ()) p -> URec (Ptr ()) p Source #

data URec (Ptr ()) (p :: k)

Used for marking occurrences of Addr#

Since: base-4.9.0.0

Instance details

Defined in GHC.Generics

data URec (Ptr ()) (p :: k) = UAddr {}
type Rep1 (URec (Ptr ()) :: k -> Type)

Since: base-4.9.0.0

Instance details

Defined in GHC.Generics

type Rep1 (URec (Ptr ()) :: k -> Type) = D1 ('MetaData "URec" "GHC.Generics" "base" 'False) (C1 ('MetaCons "UAddr" 'PrefixI 'True) (S1 ('MetaSel ('Just "uAddr#") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (UAddr :: k -> Type)))
type Rep (URec (Ptr ()) p)

Since: base-4.9.0.0

Instance details

Defined in GHC.Generics

type Rep (URec (Ptr ()) p) = D1 ('MetaData "URec" "GHC.Generics" "base" 'False) (C1 ('MetaCons "UAddr" 'PrefixI 'True) (S1 ('MetaSel ('Just "uAddr#") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (UAddr :: Type -> Type)))

class KnownNat (n :: Nat) Source #

This class gives the integer associated with a type-level natural. There are instances of the class for every concrete literal: 0, 1, 2, etc.

Since: base-4.7.0.0

Minimal complete definition

natSing