Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Building blocks for defining representations where every array is given information about which memory block is it based in, and how array elements map to memory block offsets.
There are two primary concepts you will need to understand:
- Memory blocks, which are Futhark values of type
Mem
(parametrized with their size). These correspond to arbitrary blocks of memory, and are created using theAlloc
operation. - Index functions, which describe a mapping from the index space
of an array (eg. a two-dimensional space for an array of type
[[int]]
) to a one-dimensional offset into a memory block. Thus, index functions describe how arbitrary-dimensional arrays are mapped to the single-dimensional world of memory.
At a conceptual level, imagine that we have a two-dimensional array
a
of 32-bit integers, consisting of n
rows of m
elements
each. This array could be represented in classic row-major format
with an index function like the following:
f(i,j) = i * m + j
When we want to know the location of element a[2,3]
, we simply
call the index function as f(2,3)
and obtain 2*m+3
. We could
also have chosen another index function, one that represents the
array in column-major (or "transposed") format:
f(i,j) = j * n + i
Index functions are not Futhark-level functions, but a special construct that the final code generator will eventually use to generate concrete access code. By modifying the index functions we can change how an array is represented in memory, which can permit memory access pattern optimisations.
Every time we bind an array, whether in a let
-binding, loop
merge parameter, or lambda
parameter, we have an annotation
specifying a memory block and an index function. In some cases,
such as let
-bindings for many expressions, we are free to specify
an arbitrary index function and memory block - for example, we get
to decide where Copy
stores its result - but in other cases the
type rules of the expression chooses for us. For example, Index
always produces an array in the same memory block as its input, and
with the same index function, except with some indices fixed.
Synopsis
- type LetDecMem = MemInfo SubExp NoUniqueness MemBind
- type FParamMem = MemInfo SubExp Uniqueness MemBind
- type LParamMem = MemInfo SubExp NoUniqueness MemBind
- type RetTypeMem = FunReturns
- type BranchTypeMem = BodyReturns
- data MemOp (inner :: Type -> Type) (rep :: Type)
- traverseMemOpStms :: Monad m => OpStmsTraverser m (inner rep) rep -> OpStmsTraverser m (MemOp inner rep) rep
- data MemInfo d u ret
- type MemBound u = MemInfo SubExp u MemBind
- data MemBind = ArrayIn VName IxFun
- data MemReturn
- type IxFun = IxFun (TPrimExp Int64 VName)
- type ExtIxFun = IxFun (TPrimExp Int64 (Ext VName))
- type LMAD = LMAD (TPrimExp Int64 VName)
- isStaticIxFun :: ExtIxFun -> Maybe IxFun
- type ExpReturns = MemInfo ExtSize NoUniqueness (Maybe MemReturn)
- type BodyReturns = MemInfo ExtSize NoUniqueness MemReturn
- type FunReturns = MemInfo ExtSize Uniqueness MemReturn
- noUniquenessReturns :: MemInfo d u r -> MemInfo d NoUniqueness r
- bodyReturnsToExpReturns :: BodyReturns -> ExpReturns
- type Mem rep inner = (FParamInfo rep ~ FParamMem, LParamInfo rep ~ LParamMem, HasLetDecMem (LetDec rep), RetType rep ~ RetTypeMem, BranchType rep ~ BranchTypeMem, ASTRep rep, OpReturns (inner rep), RephraseOp inner, Op rep ~ MemOp inner rep)
- class HasLetDecMem t where
- class IsOp op => OpReturns op where
- opReturns :: (Mem rep inner, Monad m, HasScope rep m) => op -> m [ExpReturns]
- varReturns :: (HasScope rep m, Monad m, Mem rep inner) => VName -> m ExpReturns
- expReturns :: (LocalScope rep m, Mem rep inner) => Exp rep -> m (Maybe [ExpReturns])
- extReturns :: [ExtType] -> [ExpReturns]
- lookupMemInfo :: (HasScope rep m, Mem rep inner) => VName -> m (MemInfo SubExp NoUniqueness MemBind)
- subExpMemInfo :: (HasScope rep m, Mem rep inner) => SubExp -> m (MemInfo SubExp NoUniqueness MemBind)
- lookupArraySummary :: (Mem rep inner, HasScope rep m, Monad m) => VName -> m (VName, IxFun (TPrimExp Int64 VName))
- lookupMemSpace :: (Mem rep inner, HasScope rep m, Monad m) => VName -> m Space
- existentialiseIxFun :: [VName] -> IxFun -> ExtIxFun
- matchBranchReturnType :: (Mem rep inner, Checkable rep) => [BodyReturns] -> Body (Aliases rep) -> TypeM rep ()
- matchPatToExp :: (Mem rep inner, LetDec rep ~ LetDecMem, Checkable rep) => Pat (LetDec (Aliases rep)) -> Exp (Aliases rep) -> TypeM rep ()
- matchFunctionReturnType :: (Mem rep inner, Checkable rep) => [FunReturns] -> Result -> TypeM rep ()
- matchLoopResultMem :: (Mem rep inner, Checkable rep) => [FParam (Aliases rep)] -> Result -> TypeM rep ()
- bodyReturnsFromPat :: Pat (MemBound NoUniqueness) -> [(VName, BodyReturns)]
- checkMemInfo :: Checkable rep => VName -> MemInfo SubExp u MemBind -> TypeM rep ()
- module Futhark.IR.Prop
- module Futhark.IR.Traversals
- module Futhark.IR.Pretty
- module Futhark.IR.Syntax
- module Futhark.Analysis.PrimExp.Convert
Documentation
type RetTypeMem = FunReturns Source #
type BranchTypeMem = BodyReturns Source #
data MemOp (inner :: Type -> Type) (rep :: Type) Source #
Instances
CanBeAliased inner => CanBeAliased (MemOp inner) Source # | |
Defined in Futhark.IR.Mem addOpAliases :: AliasableRep rep => AliasTable -> MemOp inner rep -> MemOp inner (Aliases rep) Source # | |
RephraseOp inner => RephraseOp (MemOp inner) Source # | |
Defined in Futhark.IR.Mem | |
CanBeWise inner => CanBeWise (MemOp inner) Source # | |
Defined in Futhark.IR.Mem | |
Show (inner rep) => Show (MemOp inner rep) Source # | |
OpMetrics (inner rep) => OpMetrics (MemOp inner rep) Source # | |
IndexOp (inner rep) => IndexOp (MemOp inner rep) Source # | |
OpReturns (inner rep) => OpReturns (MemOp inner rep) Source # | |
IsOp (inner rep) => IsOp (MemOp inner rep) Source # | |
AliasedOp (inner rep) => AliasedOp (MemOp inner rep) Source # | |
FreeIn (inner rep) => FreeIn (MemOp inner rep) Source # | |
TypedOp (inner rep) => TypedOp (MemOp inner rep) Source # | |
CSEInOp (op rep) => CSEInOp (MemOp op rep) Source # | |
Defined in Futhark.Optimise.CSE | |
SizeSubst (op rep) => SizeSubst (MemOp op rep) Source # | |
Rename (inner rep) => Rename (MemOp inner rep) Source # | |
Substitute (inner rep) => Substitute (MemOp inner rep) Source # | |
Defined in Futhark.IR.Mem | |
Eq (inner rep) => Eq (MemOp inner rep) Source # | |
Ord (inner rep) => Ord (MemOp inner rep) Source # | |
Defined in Futhark.IR.Mem compare :: MemOp inner rep -> MemOp inner rep -> Ordering # (<) :: MemOp inner rep -> MemOp inner rep -> Bool # (<=) :: MemOp inner rep -> MemOp inner rep -> Bool # (>) :: MemOp inner rep -> MemOp inner rep -> Bool # (>=) :: MemOp inner rep -> MemOp inner rep -> Bool # max :: MemOp inner rep -> MemOp inner rep -> MemOp inner rep # min :: MemOp inner rep -> MemOp inner rep -> MemOp inner rep # | |
Pretty (inner rep) => Pretty (MemOp inner rep) Source # | |
Defined in Futhark.IR.Mem |
traverseMemOpStms :: Monad m => OpStmsTraverser m (inner rep) rep -> OpStmsTraverser m (MemOp inner rep) rep Source #
A helper for defining TraverseOpStms
.
A summary of the memory information for every let-bound identifier, function parameter, and return value. Parameterisered over uniqueness, dimension, and auxiliary array information.
MemPrim PrimType | A primitive value. |
MemMem Space | A memory block. |
MemArray PrimType (ShapeBase d) u ret | The array is stored in the named memory block, and with the given index function. The index function maps indices in the array to element offset, not byte offsets! To translate to byte offsets, multiply the offset with the size of the array element type. |
MemAcc VName Shape [Type] u | An accumulator, which is not stored anywhere. |
Instances
Memory information for an array bound somewhere in the program.
Instances
Show MemBind Source # | |
HasLetDecMem LetDecMem Source # | |
FreeIn MemBind Source # | |
Simplifiable MemBind Source # | |
Defined in Futhark.IR.Mem | |
Rename MemBind Source # | |
Substitute MemBind Source # | |
Defined in Futhark.IR.Mem | |
Eq MemBind Source # | |
Ord MemBind Source # | |
Pretty MemBind Source # | |
Defined in Futhark.IR.Mem |
A description of the memory properties of an array being returned by an operation.
ReturnsInBlock VName ExtIxFun | The array is located in a memory block that is already in scope. |
ReturnsNewBlock Space Int ExtIxFun | The operation returns a new (existential) memory block. |
Instances
Show MemReturn Source # | |
FreeIn MemReturn Source # | |
FixExt MemReturn Source # | |
IsBodyType BodyReturns Source # | |
Defined in Futhark.IR.Mem primBodyType :: PrimType -> BodyReturns Source # | |
IsRetType FunReturns Source # | |
Defined in Futhark.IR.Mem primRetType :: PrimType -> FunReturns Source # applyRetType :: Typed dec => [FunReturns] -> [Param dec] -> [(SubExp, Type)] -> Maybe [FunReturns] Source # | |
Simplifiable MemReturn Source # | |
Defined in Futhark.IR.Mem | |
Rename MemReturn Source # | |
Substitute MemReturn Source # | |
Defined in Futhark.IR.Mem | |
Eq MemReturn Source # | |
Ord MemReturn Source # | |
Defined in Futhark.IR.Mem | |
Pretty MemReturn Source # | |
Defined in Futhark.IR.Mem | |
Simplifiable [FunReturns] Source # | |
Defined in Futhark.IR.Mem simplify :: SimplifiableRep rep => [FunReturns] -> SimpleM rep [FunReturns] Source # |
type IxFun = IxFun (TPrimExp Int64 VName) Source #
The index function representation used for memory annotations.
type ExtIxFun = IxFun (TPrimExp Int64 (Ext VName)) Source #
An index function that may contain existential variables.
type LMAD = LMAD (TPrimExp Int64 VName) Source #
The LMAD representation used for memory annotations.
type ExpReturns = MemInfo ExtSize NoUniqueness (Maybe MemReturn) Source #
The memory return of an expression. An array is annotated with
Maybe MemReturn
, which can be interpreted as the expression
either dictating exactly where the array is located when it is
returned (if Just
), or able to put it whereever the binding
prefers (if Nothing
).
This is necessary to capture the difference between an expression
that is just an array-typed variable, in which the array being
"returned" is located where it already is, and a copy
expression,
whose entire purpose is to store an existing array in some
arbitrary location. This is a consequence of the design decision
never to have implicit memory copies.
type BodyReturns = MemInfo ExtSize NoUniqueness MemReturn Source #
The return of a body, which must always indicate where returned arrays are located.
type FunReturns = MemInfo ExtSize Uniqueness MemReturn Source #
The memory return of a function, which must always indicate where returned arrays are located.
noUniquenessReturns :: MemInfo d u r -> MemInfo d NoUniqueness r Source #
type Mem rep inner = (FParamInfo rep ~ FParamMem, LParamInfo rep ~ LParamMem, HasLetDecMem (LetDec rep), RetType rep ~ RetTypeMem, BranchType rep ~ BranchTypeMem, ASTRep rep, OpReturns (inner rep), RephraseOp inner, Op rep ~ MemOp inner rep) Source #
class HasLetDecMem t where Source #
The class of pattern element decorators that contain memory information.
Instances
HasLetDecMem LetDecMem Source # | |
HasLetDecMem b => HasLetDecMem (a, b) Source # | |
Defined in Futhark.IR.Mem |
class IsOp op => OpReturns op where Source #
Nothing
Instances
OpReturns (HostOp (NoOp :: Type -> Type) (Aliases GPUMem)) Source # | |
OpReturns (HostOp (NoOp :: Type -> Type) GPUMem) Source # | |
OpReturns (HostOp (NoOp :: Type -> Type) (Wise GPUMem)) Source # | |
OpReturns (MCOp (NoOp :: Type -> Type) (Aliases MCMem)) Source # | |
OpReturns (MCOp (NoOp :: Type -> Type) MCMem) Source # | |
OpReturns (MCOp (NoOp :: Type -> Type) (Wise MCMem)) Source # | |
OpReturns (inner rep) => OpReturns (MemOp inner rep) Source # | |
OpReturns (NoOp rep) Source # | |
varReturns :: (HasScope rep m, Monad m, Mem rep inner) => VName -> m ExpReturns Source #
expReturns :: (LocalScope rep m, Mem rep inner) => Exp rep -> m (Maybe [ExpReturns]) Source #
The return information of an expression. This can be seen as the "return type with memory annotations" of the expression.
This can produce Nothing, which signifies that the result is an array layout that is not expressible as an index function.
extReturns :: [ExtType] -> [ExpReturns] Source #
lookupMemInfo :: (HasScope rep m, Mem rep inner) => VName -> m (MemInfo SubExp NoUniqueness MemBind) Source #
subExpMemInfo :: (HasScope rep m, Mem rep inner) => SubExp -> m (MemInfo SubExp NoUniqueness MemBind) Source #
lookupArraySummary :: (Mem rep inner, HasScope rep m, Monad m) => VName -> m (VName, IxFun (TPrimExp Int64 VName)) Source #
Type checking parts
matchBranchReturnType :: (Mem rep inner, Checkable rep) => [BodyReturns] -> Body (Aliases rep) -> TypeM rep () Source #
matchPatToExp :: (Mem rep inner, LetDec rep ~ LetDecMem, Checkable rep) => Pat (LetDec (Aliases rep)) -> Exp (Aliases rep) -> TypeM rep () Source #
matchFunctionReturnType :: (Mem rep inner, Checkable rep) => [FunReturns] -> Result -> TypeM rep () Source #
matchLoopResultMem :: (Mem rep inner, Checkable rep) => [FParam (Aliases rep)] -> Result -> TypeM rep () Source #
bodyReturnsFromPat :: Pat (MemBound NoUniqueness) -> [(VName, BodyReturns)] Source #
Module re-exports
module Futhark.IR.Prop
module Futhark.IR.Traversals
module Futhark.IR.Pretty
module Futhark.IR.Syntax