~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~BH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)Safe A mutable atomic integer;Create a new atomic variable initialised to the given value?Increase the atomic by the given amount. Returns the old value.BBitwise AND the atomic with the given value. Return the old value.c[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions) /Scalar types supported in array computations/ Integral types: * Int * Int8 * Int16 * Int32 * Int64 * Word * Word8 * Word16 * Word32 * Word64 * CShort * CUShort * CInt * CUInt * CLong * CULong * CLLong * CULLong Floating types: * Float * Double * CFloat * CDouble Non-numeric types: * Bool * Char * CChar * CSChar * CUChar Note that 'Int' has the same bit width as in plain Haskell computations, and 'Float' and 'Double' represent IEEE single and double precision floating point numbers, respectively.None%&*,/09;DQRS8Boundary condition specification for stencil operations.T,clamp coordinates to the extent of the arrayU*mirror coordinates beyond the array extentV)wrap coordinates around on each dimensionW-use a constant value for outlying coordinatesAConstraint that values of these two types have the same bit widthXAll scalar typesY Bounded typesZ Numeric types[Non-numeric types\Floating types]Integral types1All scalar element types implement Eq, Ord & Enum'Bounded element types implement Bounded*Numeric element types implement Num & Real2Non-numeric types supported in array computations.5Floating-point types supported in array computations./Integral types supported in array computations.STUVWXYZ[\]      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~g   !"#$%&'SWTUVXYZ[\]     STUVWXYZ[\]      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ [2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonell [2013..2017] Robert Clifton-EverestBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)Safe %&*9;<=DRHConversion between surface product types and our product representation.DWe parameterise our products by a constraint on their elements (the cst| argument). Every element in the product must obey this constraint, but the products themselves do necessarily not have to.Product reification(Type-safe projection indices for tuples.:NB: We index tuples by starting to count from the *right*!  H[2015..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)Safe$/ H[2015..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)Safe!"  `[2015..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonell, Robert Clifton-EverestBSD31Robert Clifton-Everest <robertce@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneBLjA lifetime represents a value with attached finalizers. This is similar to the functionality provided by System.Mem.Weak-, but has the following stronger properties:FUnless explicitly forced, finalizers will not fire until after the K has become unreachable, where "reachability" is the same as defined in System.Mem.Weak7. That is to say, there is no issue with creating a U for a non-primitve type and finalizers firing while an object is still reachable.YFinalizers are fired sequentially in reverse of the order in which they were attached.&As the finalizers are attached to the l and not the underlying value, there is no danger in storing it UNPACKED as part of another structure.Construct a new  from the given value.5This provides a way of looking at the value inside a 9. The supplied function is executed immediately and the L kept alive throughout its execution. It is important to not let the value leak= outside the function, either by returning it or by lazy IO.nEnsure that the lifetime is alive at the given place in a sequence of IO actions. Does not force the payload.Attaches a finalizer to a  . Like in System.Mem.Weak, there is no guarantee that the finalizers will eventually run. If they do run, they will be executed in the order in which they were supplied.fCauses any finalizers associated with the given lifetime to be run immediately on the calling thread.Because the finalizer is run on the calling thread. Care should be taken to ensure that the it does not try to acquire any locks the calling thread might already possess. This can result in deadlock and is in contrast to calling   on  .Create a weak pointer from a  to the supplied value.fBecause weak pointers have their own concept of finalizers, it is important to note these behaviours:Calling   causes the finalizers attached to the lifetime to be scheduled, and run in the correct order, but does not guarantee they will execute on the calling thread.If  deRefWeakP returns Nothing, there is no guarantee that the finalizers have already run.HRetrieve the value from a lifetime. This is unsafe because, unless the R is still reachable, the finalizers may fire, potentially invalidating the value.  c[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)SafeM 55H[2009..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None!"Issue an internal error message'$internalError :: String -> String -> aSThrow an error if the condition evaluates to False, otherwise evaluate the result.4$internalCheck :: String -> String -> Bool -> a -> aKThrow an error if the index is not in range, otherwise evaluate the result..$boundsCheck :: String -> Int -> Int -> a -> a<Print a warning message if the condition evaluates to False.6$internalWarning :: String -> String -> Bool -> a -> a H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)Safe!"Launch a monitoring server that will collect statistics on the running application. This should be called as soon as the application starts. The program will need to be run with the RTS option -T.aInitialise and return the Accelerate monitoring store. To enable monitoring of your application: import Data.Array.Accelerate.Debug import System.Metrics import System.Remote.Monitoring main :: IO () main = do store <- initAccMetrics registerGcMetrics store -- optional server <- forkServerWith store "localhost" 8000 ...qExecute the given action and assign the elapsed wall-clock time as active time for the given processing element. _Record the given number of seconds as active processing time for the given processing element.                 c[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None QRJA bit of a hack to get the command line options processing out of the way.We would like to have this automatically called once during program initialisation, so that our command-line debug flags between +ACC .. [-ACC] don't interfere with other programs. Hacks beget hacks beget hacks...7Conditional execution of a monadic debugging expressionThe opposite of + !"#$%&'()*+,-./0123456789:;  !"#$%&'()*+,-./056789( !"#$%&'()*+,-./0123456789:;c[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None'<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ab LMNOPQRWZ<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abc[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NonecShow a signed d. value using SI unit prefixes. In the call to: showFFloatSIBase prec base valIf prec is e. the value is shown to full precision, and if prec is f d, then at most d1 digits are shown after the decimal place. Here base represents the increment size between multiples of the original unit. For measures in base-10 this will be 1000 and for values in base-2 this is usually 1024, for example when measuring seconds versus bytes, respectively.gThe g function outputs the message given as its second argument when the debug mode indicated by the first argument is enabled, before returning the third argument as its result. The message is prefixed with a time stamp.hThe h function outputs the trace message together with a time stamp from the IO monad. This sequences the output with respect to other IO actions.iThe i function behaves like gp with the difference that the message is emitted to the eventlog, if eventlog profiling is enabled at runtime.j3Print a message prefixed with the current CPU time.kThe kf function emits a message to the eventlog, if eventlog profiling is available and enabled at runtime. Compared to i, k7 sequences the event with respect to other IO actions.cghijkcghijkcghijkH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NonelMExecute an action and time the results. If GC stats have been enabled (with +RTS -tq for example) then timing and memory usage information is displayed, otherwise only timing information is shown.lmlmlmH[2009..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneBn2Spawn an asynchronous action in a separate thread.oLike n , but using p internally.qLike n , but using r internally.sRBlock the calling thread until the computation completes, then return the result.taTest whether the asynchronous computation has already completed. If so, return the result, else e.u*Cancel a running asynchronous computation. vwnoqxstuyzvnoqstu vwnoqxstuyz`[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonell, Robert Clifton-EverestBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None{A uniquely identifiable array.For the purposes of memory management, we use arrays as keys in a table. For this reason we need a way to uniquely identify each array we create. We do this by attaching a unique identifier to each array.Note: [Unique array strictness]nThe actual array data is in many cases unnecessary. For discrete memory backends such as for GPUs, we require the unique identifier to track the data in the remote memory space, but the data will in most cases never be copied back to the host. Thus, the array payload field is only lazily allocated, and we should be careful not to make this field overly strict.|Create a new UniqueArray},Access the pointer backing the unique array.The array data is kept alive at least during the whole action, even if it is not directly used inside. Note that it is not safe to return the pointer from the action and use it after the action completes. All uses of the pointer should be inside the bracketed function.~-Extract the pointer backing the unique array.This is potentially unsafe, as if the argument is the last occurrence of this unique array then the finalisers will be run, potentially invalidating the plain pointer just obtained. See also: , .Ensure that the unique array is alive at the given place in a sequence of IO actions. Note that this does not force the actual array payload.See: [Unique array strictness] {|}~{|}~{|}~[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonell [2013..2017] Robert Clifton-Everest [2014..2014] Frederik M. MadsenBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%&9:;DLQRTXGeneralised array index, which may index only in a subset of the dimensions of a shape.Slice representation7Class of slice representations (which are nested pairs)Index representation7Class of index representations (which are nested pairs)1Project the shape of a slice from the full shape.YEnumerate all slices within a given bound. The innermost dimension changes most rapidly.See  for an example.! c[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%&/0BDRTGADT to reify the  class.Mutable array representationImmutable array representation=Safe combination of creating and fast freezing of array data.Register the given function as the callback to use to allocate new array data on the host containing the specified number of bytes. The returned array must be pinned (with respect to Haskell's GC), so that it can be passed to foreign code.dAllocate the given number of bytes with 16-byte alignment. This is essential for SIMD instructions.\Additionally, we return a plain ForeignPtr, which unlike a regular ForeignPtr created with  carries no finalisers. It is an error to try to add a finaliser to the plain ForeignPtr. For our purposes this is fine, since in Accelerate finalisers are handled using Lifetime      !"#$%&'()*+,-./0123456789:;SQ       !"#$%&'()*+,-./0123456789:;{[2015..2017] Manuel M T Chakravarty, Gabriele Keller, Robert Clifton-Everest [2016..2017] Trevor L. McDonellBSD31Robert Clifton-Everest <robertce@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None*DR <Accelerate backends can provide an instance of this class in order to take advantage of the automated memory managers we provide as part of the base package.=,Pointers into this particular remote memory.>fAttempt to allocate the given number of bytes in the remote memory space. Returns Nothing on failure.?ICopy the given number of elements from the host array into remote memory.@GCopy the given number of elements from remote memory to the host array.ACast a remote pointer.B3Returns the total remote memory available in bytes.C/Returns, in bytes, the available remote memory.D"The chunk allocation size (bytes).E/Matches array element types to primitive types. <=>?@ABCDE <=>?@ABCDE<=>?@ABCDE[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonell [2013..2017] Robert Clifton-Everest [2014..2014] Frederik M. MadsenBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%&*/09:;DLQRT0FGeneralised array division, like above but use for splitting an array into many subarrays, as opposed to extracting a single subarray.^$Slices, aka generalised indices, as nQ-tuples and mappings of slice indices to slices, co-slices, and slice dimensionsc.Shapes and indices of multi-dimensional arraysGNumber of dimensions of a shape or index (>= 0).H2Total number of elements in an array of the given shape.IEmpty shape.J,Magic value identifying elements ignored in permute.K$Yield the intersection of two shapesLYield the union of two shapesMrMap a multi-dimensional index into one in a linear, row-major representation of the array (first argument is the shape!, second argument is the index).N Inverse of M.O'Apply a boundary condition to an index.PIterate through the entire shape, applying the function; third argument combines results and fourth is returned in case of an empty iteration space; the index space is traversed in row-major order.Q Variant of P without an initial valueR)Convert a minpoint-maxpoint index into a shape.S Convert a shape into a minpoint-maxpoint index.T(Convert a shape to a list of dimensions.U*Convert a list of dimensions into a shape.V,The slice index for slice specifier 'Any sh'WJThe slice index for specifying a slice with only the Z component projectedn/Segment descriptor (vector of segment lengths).fTo represent nested one-dimensional arrays, we use a flat array of data values in conjunction with a segment descriptor-, which stores the lengths of the subarrays.o"Vectors are one-dimensional arraysp$Scalars arrays hold a single elementq)Dense, regular, multi-dimensional arrays.The q is the core computational unit of Accelerate; all programs in Accelerate take zero or more arrays as input and produce one or more arrays as output. The q type has two type parameters:shu: is the shape of the array, tracking the dimensionality and extent of each dimension of the array; for example, l for one-dimensional os, k) for two-dimensional matrices, and so on.eE: represents the type of each element of the array; for example,  ,   , et cetera.Array data is store unboxed in an unzipped struct-of-array representation. Elements are laid out in row-major order (the right-most index of a cQ is the fastest varying). The allowable array element types are members of the s" class, which roughly consists of:;Signed and unsigned integers (8, 16, 32, and 64-bits wide).4Floating point numbers (single and double precision)  ()Shapes formed from z and (x)@Nested tuples of all of these, currently up to 15-elements wide. Note that qj itself is not an allowable element type---there are no nested arrays in Accelerate, regular arrays only!If device and host memory are separate, arrays will be transferred to the device when necessary (possibly asynchronously and in parallel with other tasks) and cached on the device if sufficient memory is available. Arrays are made available to embedded language computations via .PSection "Getting data in" lists functions for getting data into and out of the q type.XTuple reificationY.Tuples of Arrays. Note that this carries the r! class constraint rather than s" in the case of tuples of scalars.ZAWe represent tuples as heterogeneous lists, typed by a type list.[EThe tuple representation is equivalent to the product representation.rr) consists of nested tuples of individual qcs, currently up to 15-elements wide. Accelerate computations can thereby return multiple results.sThe s class characterises the allowable array element types, and hence the types which can appear in scalar Accelerate expressions.Accelerate arrays consist of simple atomic types as well as nested tuples thereof, stored efficiently in memory as consecutive unpacked elements without pointers. It roughly consists of::Signed and unsigned integers (8, 16, 32, and 64-bits wide)4Floating point numbers (single and double precision)  ()Shapes formed from z and (x)?Nested tuples of all of these, currently up to 15-elements wideAdding new instances for s~ consists of explaining to Accelerate how to map between your data type and a (tuple of) primitive values. For examples see:"Data.Array.Accelerate.Data.Complex!Data.Array.Accelerate.Data.Monoid 5https://hackage.haskell.org/package/linear-acceleratelinear-accelerate 5https://hackage.haskell.org/package/colour-acceleratecolour-accelerate\Type representation mappingWe represent tuples by using '()' and '(,)' as type-level nil and snoc to construct snoc-lists of types, and are flattened all the way down to primitive types.]wMarker for arbitrary shapes in slices descriptors, where it is desired to split along an unknown number of dimensions.*For example, in the following definition, ]P matches against any shape and flattens everything but the innermost dimension. ivectors :: (Shape sh, Elt e) => Acc (Array (sh:.Int) e) -> Seq [Vector e] vectors = toSeq (Divide :. All)^GMarker for splitting along an entire dimension in division descriptors.;For example, when used in a division descriptor passed to , a ^n indicates that the array should be divided along this dimension forming the elements of the output sequence.t#Marker for arbitrary dimensions in  ! and  " descriptors.t< can be used in the leftmost position of a slice instead of zE, indicating that any dimensionality is admissible in that position.See  ! and  " for examples.v Marker for entire dimensions in  ! and  " descriptors.Occurrences of vZ indicate the dimensions into which the array's existing extent will be placed unchanged.See  ! and  " for examples.x.Increase an index rank by one dimension. The x7 operator is used to construct both values and types.z Rank-0 index_Convenience functions`Yield an array's shapeaArray indexing|VCreate an array from its representation function, applied at each index of the array.bDCreate a vector from the concatenation of the given list of vectors.c.Creates a new, uninitialized Accelerate array.}.Convert elements of a list into an Accelerate q.*This will generate a new multidimensional qy of the specified shape and extent by consuming elements from the list and adding them to the array in row-major order.$fromList (Z:.10) [0..] :: Vector Int&Vector (Z :. 10) [0,1,2,3,4,5,6,7,8,9]PNote that we pull elements off the list lazily, so infinite lists are accepted:2fromList (Z:.5:.10) (repeat 0) :: Array DIM2 FloatMatrix (Z :. 5 :. 10)5 [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,5 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,5 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,5 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,5 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]You can also make use of the OverloadedLists6 extension to produce one-dimensional vectors from a finite list.[0..9] :: Vector Int&Vector (Z :. 10) [0,1,2,3,4,5,6,7,8,9]Note that this requires first traversing the list to determine its length, and then traversing it a second time to collect the elements into the array, thus forcing the spine of the list to be manifest on the heap.~Convert an accelerated q to a list in row-major order.d!Nicely format a shape as a stringe1Project the shape of a slice from the full shape.fYEnumerate all slices within a given bound. The innermost dimension changes most rapidly.Example: let slix = sliceIndex (undefined :: Z :. Int :. Int :. All) sh = Z :. 2 :. 3 :. 1 :: DIM3 in enumSlices slix sh :: [ Z :. Int :. Int :. All ]Fgh^_`abcGHIJKLMNOPQRSTUVWdefghijklmnopqiXYjkZlm[rnopqrstuvwxyz{|}s~\]^tuvwxyz{_`a|bc}~defgFgh^_`abcILKHJPMNGTOQRSUVWdefghijklmnopqiXYjkZlm[rnopqrstuvwxyz{|}s~\]^tuvwxyz{`a|bc}~defFgh^_`abcGHIJKLMNOPQRSTUVWdefghijklmnopqiXYjkZlm[rnopqrstuvwxyz{|}s~\]^tuvwxyz{_`a|bc}~defx3y3a9 #`[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonell, Robert Clifton-EverestBSD31Robert Clifton-Everest <robertce@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%&*0<=DMORT$[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonell [2010..2011] Ben Lever [2013..2017] Robert Clifton-Everest [2014..2014] Frederik M. MadsenBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%&/09:;<=DOQRTPrimitive scalar operationsPrimitive constant valuesParametrised open expressions using de Bruijn indices for variables ranging over tuples of scalars and arrays of tuples. All code, except Cond, is evaluated eagerly. N-tuples are represented as nested pairs.SThe data type is parametrised over the surface types (not the representation type).0Vanilla expression without free scalar variables5Parametrised expression without free scalar variablesVanilla open expression.Vanilla function without free scalar variables3Parametrised function without free scalar variables!Vanilla open function abstraction&Parametrised open function abstractionGADT reifying the  class.Operations on stencils.dCollective array computations parametrised over array variables represented with de Bruijn indices.Scalar functions and expressions embedded in well-formed array computations cannot contain free scalar variable indices. The latter cannot be bound in array computations, and hence, cannot appear in any well-formed program.The let-form is used to represent the sharing discovered by common subexpression elimination as well as to control evaluation order. (We need to hoist array expressions out of scalar expressions - they occur in scalar indexing and in determining an arrays shape.)UThe data type is parameterised over the surface types (not the representation type).|We use a non-recursive variant parametrised over the recursive closure, to facilitate attribute calculation in the backend.,Closed array expression aka an array program?Vanilla array-computation function without free array variablesDParametrised array-computation function without free array variables9Function abstraction over parametrised array computations      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLONPeb^QMRSTUVWXYZ[\]_`acdfghijklmnopq{trsuvwxyz|}~BA      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~%H[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None %&/MOQRT--&E[2010..2011] Ben Lever [2010..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%&QRTCalculate the offset coordinates for each stencil element relative to the focal point. The coordinates are returned as a flattened list from the bottom-left element to the top-right. This ordering matches the Var indexing order./Position calculation on reified stencil values.'c[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None %&9;MOQRT               ([2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonell [2013..2017] Robert Clifton-Everest [2014..2014] Frederik M. MadsenBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%&/09:;<=DQRTScalar expressions to parametrise collective array operations, themselves parameterised over the type of collective array operations. The type R represents embedded scalar expressions. The collective operations of Accelerate ? consist of many scalar expressions executed in data-parallel.^Note that scalar expressions can not initiate new collective operations: doing so introduces nested data parallelismv, which is difficult to execute efficiently on constrained hardware such as GPUs, and is thus currently unsupported.=Array-valued collective computations without a recursive knotAccelerate is an embedded languageV that distinguishes between vanilla arrays (e.g. in Haskell memory on the CPU) and embedded arrays (e.g. in device memory on a GPU), as well as the computations on both of these. Since Accelerate is an embedded language, programs written in Accelerate are not compiled by the Haskell compiler (GHC). Rather, each Accelerate backend is a runtime compilerX which generates and executes parallel SIMD code of the target language at application runtime.The type constructor B represents embedded collective array operations. A term of type Acc aN is an Accelerate program which, once executed, will produce a value of type a (an q or a tuple of r"). Collective operations of type Acc a comprise many scalar expressions, wrapped in type constructor , which will be executed in parallel. Although collective operations comprise many scalar operations executed in parallel, scalar operations cannotW initiate new collective operations: this stratification between scalar operations in  and array operations in  helps statically exclude nested data parallelismR, which is difficult to execute efficiently on constrained hardware such as GPUs.<For example, to compute a vector dot product we could write: dotp :: Num a => Vector a -> Vector a -> Acc (Scalar a) dotp xs ys = let xs' = use xs ys' = use ys in fold (+) 0 ( zipWith (*) xs' ys' ) The function dotp& consumes two one-dimensional arrays (o&s) of values, and produces a single (p?) result as output. As the return type is wrapped in the type V, we see that it is an embedded Accelerate computation - it will be evaluated in the objectC language of dynamically generated parallel code, rather than the meta language of vanilla Haskell.As the arguments to dotpo are plain Haskell arrays, to make these available to Accelerate computations they must be embedded with the   function.An Accelerate backend is used to evaluate the embedded computation and return the result back to vanilla Haskell. Calling the run function of a backend will generate code for the target architecture, compile, and execute it. For example, the following backends are available: 9http://hackage.haskell.org/package/accelerate-llvm-nativeaccelerate-llvm-native!: for execution on multicore CPUs 6http://hackage.haskell.org/package/accelerate-llvm-ptxaccelerate-llvm-ptx+: for execution on NVIDIA CUDA-capable GPUs See also , which encapsulates embedded scalar computations. Fusion:Array computations of type  will be subject to  array fusion&; Accelerate will combine individual  computations into a single computation, which reduces the number of traversals over the input data and thus improves performance. As such, it is often useful to have some intuition on when fusion should occur.IThe main idea is to first partition array operations into two categories: !Element-wise operations, such as ), * , and +U. Each element of these operations can be computed independently of all others.Collective operations such as ,, -, and .|. To compute each output element of these operations requires reading multiple elements from the input array(s).Element-wise operations fuse together whenever the consumer operation uses a single element of the input array. Element-wise operations can both fuse their inputs into themselves, as well be fused into later operations. Both these examples should fuse into a single loop: 'map -> reverse -> reshape -> map -> map Pmap -> backpermute -> zipWith -> map generate ->YIf the consumer operation uses more than one element of the input array (typically, via * indexing an array multiple times), then the input array will be completely evaluated first; no fusion occurs in this case, because fusing the first operation into the second implies duplicating work.On the other hand, collective operations can fuse their input arrays into themselves, but on output always evaluate to an array; collective operations will not be fused into a later step. For example: ; use -> zipWith -> fold |-> map generate -> Here the element-wise sequence ( + * + /L) will fuse into a single operation, which then fuses into the collective ,. operation. At this point in the program the ,/ must now be evaluated. In the final step the )! reads in the array produced by ,%. As there is no fusion between the , and ); steps, this program consists of two "loops"; one for the  + * + / + , step, and one for the final ) step.JYou can see how many operations will be executed in the fused program by  -ing the + program, or by using the debugging option  -ddump-dot- to save the program as a graphviz DOT file."As a special note, the operations 0 and 1x, when applied to a real array, are executed in constant time, so in this situation these operations will not be fused. Tips:Since  represents embedded computations that will only be executed when evaluated by a backend, we can programatically generate these computations using the meta language Haskell; for example, unrolling loops or embedding input values into the generated code.<It is usually best to keep all intermediate computations in , and only run the computation at the very end to produce the final result. This enables optimisations between intermediate results (e.g. array fusion) and, if the target architecture has a separate memory space as is the case of GPUs, to prevent excessive data transfers.kScalar expression inlet: make a Haskell value available for processing in an Accelerate scalar expression.?Note that this embeds the value directly into the expression. Depending on the backend used to execute the computation, this might not always be desirable. For example, a backend that does external code generation may embed this constant directly into the generated code, which means new code will need to be generated and compiled every time the value changes. In such cases, consider instead lifting scalar values into (singleton) arrays so that they can be passed as an input to the computation and thus the value can change without the need to generate fresh code. !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~SWTUV 6"52.#$%&'()*+,-/0134!7QE@DSG=>:;<?BACFHIJKLMNOPRT89UVWXYZ[\]^_`abcdefghijklmnopqr|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~00002H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None*9:;vName the upper and lower limits of a type. Types which are not totally ordered may still have upper and lower bounds.'     IJ'     3H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None*9:;*Operations over sequentially ordered types4H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None9:;The  class defines equality  and inequality $ for scalar Accelerate expressions.For convenience, we include s as a superclass.Conjunction: True if both arguments are true. This is a short-circuit operator, so the second argument will be evaluated only if the first is true.Disjunction: True if either argument is true. This is a short-circuit operator, so the second argument will be evaluated only if the first is false.Logical negation2 !"#$%&'()*+,-./0123456789:;<=>?@A0 !"#$%&'()*+,-./0123456789:;<=>?@A44325H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None*9:;Basic numeric classBCDEFGHIJKLMNOPQRSTUVWKLMNBCDEFGHIJKLMNOPQRSTUVW6H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None*9:;,Fractional numbers, supporting real divisionXYZ[GHXYZ[7H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None*9:;<Trigonometric and hyperbolic functions and related functions\]^_;<>=?/0123456789:@\]^_8H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None9:;The $ class for totally ordered datatypes3`abcdefghijklmnopqrstuvwxyz{|}~-`abcdefghijklmnopqrstuvwxyz{|}~44449H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None*9:;:H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None*9:;.Integral numbers, supporting integral divisionABCDEF;H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None*:<=)Accelerate lacks a most-general lossless  type, which the standard  function uses as an intermediate value when coercing from integral types. Instead, we use this class to capture a direct coercion between two types.$General coercion from integral types<H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None *9:;<=(Accelerate lacks an arbitrary-precision => type, which the standard =? uses as an intermediate value when coercing to floating-point types. Instead, we use this class to capture a direct coercion between to types."General coercion to floating types@H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None*9:;#Extracting components of fractions. truncate x returns the integer nearest x between zero and x x returns the nearest integer to x; the even integer if x% is equidistant between two integers x) returns the least integer not less than x x/ returns the greatest integer not greater than xGeneralisation of D to any instance of Generalisation of C to any instance of Generalisation of A to any instance of   AH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None *69:;TSEfficient, machine-independent access to the components of a floating-point number4The radix of the representation (often 2) (constant)The number of digits of  in the significand (constant)@The lowest and highest values the exponent may assume (constant)AReturn the significand and an appropriately scaled exponent. if (m,n) =  x then  x = m*b^^n, where b is the floating-point radix (). Furthermore, either m and n are both zero, or  b^(d-1) <= abs m < b^d, where d =  x. Inverse of 'Corresponds to the second component of &Corresponds to the first component of AMultiply a floating point number by an integer power of the radix6 if the argument is an IEEE "not-a-number" (NaN) value9 if the argument is an IEEE infinity or negative-infinityE if the argument is too small to be represented in normalized format) if the argument is an IEEE negative zero1 if the argument is an IEEE floating point numberUA version of arctangent taking two real floating-point arguments. For real floating x and y,  y x[ computes the angle (from the positive x-axis) of the vector from the origin to the point (x,y).  y x returns a value in the range [-pi, pi].BH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneTJI@?>=<;:9876543210/HGFEDCBAMNLK [2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonell [2014..2014] Frederik M. MadsenBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None $*:DQRT4eMake an array from vanilla Haskell available for processing within embedded Accelerate computations.PDepending upon which backend is used to eventually execute array computations, * may entail data transfer (e.g. to a GPU)./ is overloaded so that it can accept tuples of r:3let vec = fromList (Z:.10) [0..] :: Array DIM1 Int&Vector (Z :. 10) [0,1,2,3,4,5,6,7,8,9]6let mat = fromList (Z:.5:.10) [0..] :: Array DIM2 IntmatMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]2let vec' = use vec :: Acc (Array DIM1 Int)2let mat' = use mat :: Acc (Array DIM2 Int)Blet tup = use (vec, mat) :: Acc (Array DIM1 Int, Array DIM2 Int)[Construct a singleton (one element) array from a scalar value (or tuple of scalar values).FReplicate an array across one or more dimensions as specified by the  generalised, array index provided as the first argument.(For example, given the following vector: let vec = fromList (Z:.10) [0..]&Vector (Z :. 10) [0,1,2,3,4,5,6,7,8,9]u...we can replicate these elements to form a two-dimensional array either by replicating those elements as new rows:*replicate (lift (Z :. 4 :. All)) (use vec)Matrix (Z :. 4 :. 10)! [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,! 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,! 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,! 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]...or as columns:*replicate (lift (Z :. All :. 4)) (use vec) Matrix (Z :. 10 :. 4) [ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9]Replication along more than one dimension is also possible. Here we replicate twice across the first dimension and three times across the third dimension:/replicate (lift (Z :. 2 :. All :. 3)) (use vec)Array (Z :. 2 :. 10 :. 3) [0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8,9,9,9,0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,8,8,8,9,9,9] The marker tf can be used in the slice specification to match against some arbitrary dimension. For example, here t/ matches against whatever shape type variable sh takes. ~rep0 :: (Shape sh, Elt e) => Exp Int -> Acc (Array sh e) -> Acc (Array (sh :. Int) e) rep0 n a = replicate (lift (Any :. n)) a$let x = unit 42 :: Acc (Scalar Int) rep0 10 x0Vector (Z :. 10) [42,42,42,42,42,42,42,42,42,42]rep0 5 (use vec) Matrix (Z :. 10 :. 5) [ 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9] Of course, t and v can be used together. rep1 :: (Shape sh, Elt e) => Exp Int -> Acc (Array (sh :. Int) e) -> Acc (Array (sh :. Int :. Int) e) rep1 n a = A.replicate (lift (Any :. n :. All)) arep1 5 (use vec)Matrix (Z :. 5 :. 10)! [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,! 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,! 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,! 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,! 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];Construct a new array by applying a function to each index.CFor example, the following will generate a one-dimensional array (o") of three floating point numbers:generate (index1 3) (\_ -> 1.2)Vector (Z :. 3) [1.2,1.2,1.2]Or equivalently:fill (constant (Z :. 3)) 1.2Vector (Z :. 3) [1.2,1.2,1.2]5The following will create a vector with the elements [1..10]:-generate (index1 10) (\ix -> unindex1 ix + 1)'Vector (Z :. 10) [1,2,3,4,5,6,7,8,9,10] NOTE:Using ], it is possible to introduce nested data parallelism, which will cause the program to fail.yIf the index given by the scalar function is then used to dispatch further parallel work, whose result is returned into . terms by array indexing operations such as () or CD, the program will fail with the error: './Data/Array/Accelerate/Trafo/Sharing.hs:447 (convertSharingExp): inconsistent valuation @ shared 'Exp' tree ...'.@Change the shape of an array without altering its contents. The 4 of the source and result arrays must be identical. +precondition: shapeSize sh == shapeSize sh'-If the argument array is manifest in memory, H is a NOP. If the argument is to be fused into a subsequent operation, ; corresponds to an index transformation in the fused code.Index an array with a  generalised array index, supplied as the second argument. The result is a new array (possibly a singleton) containing the selected dimensions (vs) in their entirety. is the opposite of , and can be used to cut out@ entire dimensions. For example, for the two dimensional array mat:#let mat = fromList (Z:.5:.10) [0..]matMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]...will can select a specific row to yield a one dimensional result by fixing the row index (2) while allowing the column index to vary (via v):&slice (use mat) (lift (Z :. 2 :. All))0Vector (Z :. 10) [20,21,22,23,24,25,26,27,28,29]!A fully specified index (with no v6s) returns a single element (zero dimensional array).$slice (use mat) (lift (Z :. 4 :. 2)) Scalar Z [42] The marker ta can be used in the slice specification to match against some arbitrary (lower) dimension. Here t' matches whatever shape type variable sh takes: xsl0 :: (Shape sh, Elt e) => Acc (Array (sh:.Int) e) -> Exp Int -> Acc (Array sh e) sl0 a n = A.slice a (lift (Any :. n)) let vec = fromList (Z:.10) [0..]sl0 (use vec) 4 Scalar Z [4]sl0 (use mat) 4Vector (Z :. 5) [4,14,24,34,44] Of course, t and v can be used together. sl1 :: (Shape sh, Elt e) => Acc (Array (sh:.Int:.Int) e) -> Exp Int -> Acc (Array (sh:.Int) e) sl1 a n = A.slice a (lift (Any :. n :. All))sl1 (use mat) 40Vector (Z :. 10) [40,41,42,43,44,45,46,47,48,49]&let cube = fromList (Z:.3:.4:.5) [0..]cubeArray (Z :. 3 :. 4 :. 5) [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59]sl1 (use cube) 2Matrix (Z :. 3 :. 5) [ 10, 11, 12, 13, 14, 30, 31, 32, 33, 34, 50, 51, 52, 53, 54]2Apply the given function element-wise to an array. /map f [x1, x2, ... xn] = [f x1, f x2, ... f xn]Apply the given binary function element-wise to the two arrays. The extent of the resulting array is the intersection of the extents of the two source arrays.hReduction of the innermost dimension of an array of arbitrary rank. The first argument needs to be an  associative function to enable an efficient parallel implementation. The initial element does not need to be an identity element of the combination function.#let mat = fromList (Z:.5:.10) [0..]matMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]fold (+) 42 (use mat)$Vector (Z :. 5) [87,187,287,387,487]Reductions with non-commutative operators are supported. For example, the following computes the maximum segment sum problem along each innermost dimension of the array. 6https://en.wikipedia.org/wiki/Maximum_subarray_problem maximumSegmentSum :: forall sh e. (Shape sh, Num e, Ord e) => Acc (Array (sh :. Int) e) -> Acc (Array sh e) maximumSegmentSum = map (\v -> let (x,_,_,_) = unlift v :: (Exp e, Exp e, Exp e, Exp e) in x) . fold1 f . map g where f :: (Num a, Ord a) => Exp (a,a,a,a) -> Exp (a,a,a,a) -> Exp (a,a,a,a) f x y = let (mssx, misx, mcsx, tsx) = unlift x (mssy, misy, mcsy, tsy) = unlift y in lift ( mssx `max` (mssy `max` (mcsx+misy)) , misx `max` (tsx+misy) , mcsy `max` (mcsx+tsy) , tsx+tsy ) g :: (Num a, Ord a) => Exp a -> Exp (a,a,a,a) g x = let y = max x 0 in lift (y,y,y,x)4let vec = fromList (Z:.10) [-2,1,-3,4,-1,2,1,-5,4,0]maximumSegmentSum (use vec) Scalar Z [6] See also EQ, which can be a useful way to compute multiple results from a single reduction. Variant of y that requires the reduced array to be non-empty and doesn't need an default value. The first argument needs to be an  associativew function to enable an efficient parallel implementation. The initial element does not need to be an identity element.%Segmented reduction along the innermost dimension of an array. The segment descriptor specifies the lengths of the logical sub-arrays, each of which is reduced independently. The innermost dimension must contain at least as many elements as required by the segment descriptor (sum thereof).#let seg = fromList (Z:.4) [1,4,0,3]segVector (Z :. 4) [1,4,0,3]#let mat = fromList (Z:.5:.10) [0..]matMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]!foldSeg (+) 0 (use mat) (use seg)Matrix (Z :. 5 :. 4) [ 0, 10, 0, 18, 10, 50, 0, 48, 20, 90, 0, 78, 30, 130, 0, 108, 40, 170, 0, 138] Variant of  that requires all segments of the reduced array to be non-empty and doesn't need a default value. The segment descriptor specifies the length of each of the logical sub-arrays.Data.List style left-to-right scan along the innermost dimension of an arbitrary rank array. The first argument needs to be an  associativen function to enable efficient parallel implementation. The initial value (second argument) may be arbitrary.-scanl (+) 10 (use $ fromList (Z :. 10) [0..])2Array (Z :. 11) [10,10,11,13,16,20,25,31,38,46,55]1scanl (+) 0 (use $ fromList (Z :. 4 :. 10) [0..])Matrix (Z :. 4 :. 11)5 [ 0, 0, 1, 3, 6, 10, 15, 21, 28, 36, 45,5 0, 10, 21, 33, 46, 60, 75, 91, 108, 126, 145,5 0, 20, 41, 63, 86, 110, 135, 161, 188, 216, 245,5 0, 30, 61, 93, 126, 160, 195, 231, 268, 306, 345] Variant of w, where the last element (final reduction result) along each dimension is returned separately. Denotationally we have: _scanl' f e arr = (init res, unit (res!len)) where len = shape arr res = scanl f e arr;let (res,sum) = scanl' (+) 0 (use $ fromList (Z:.10) [0..])res+Vector (Z :. 10) [0,0,1,3,6,10,15,21,28,36]sum Scalar Z [45]?let (res,sums) = scanl' (+) 0 (use $ fromList (Z:.4:.10) [0..])resMatrix (Z :. 4 :. 10)0 [ 0, 0, 1, 3, 6, 10, 15, 21, 28, 36,0 0, 10, 21, 33, 46, 60, 75, 91, 108, 126,0 0, 20, 41, 63, 86, 110, 135, 161, 188, 216,0 0, 30, 61, 93, 126, 160, 195, 231, 268, 306]sums Vector (Z :. 4) [45,145,245,345]Data.List style left-to-right scan along the innermost dimension without an initial value (aka inclusive scan). The array must not be empty. The first argument needs to be an  associative# function. Denotationally, we have: %scanl1 f e arr = tail (scanl f e arr)+scanl (+) (use $ fromList (Z:.4:.10) [0..])Matrix (Z :. 4 :. 10)2 [ 0, 1, 3, 6, 10, 15, 21, 28, 36, 45,2 10, 21, 33, 46, 60, 75, 91, 108, 126, 145,2 20, 41, 63, 86, 110, 135, 161, 188, 216, 245,2 30, 61, 93, 126, 160, 195, 231, 268, 306, 345]Right-to-left variant of .Right-to-left variant of .Right-to-left variant of .:Generalised forward permutation operation (array scatter).0Forward permutation specified by a function mapping indices from the source array to indices in the result array. The result array is initialised with the given defaults and any further values that are permuted into the result array are added to the current value using the given combination function.!The combination function must be  associative and  commutative/. Elements that are mapped to the magic value * by the permutation function are dropped.For example, we can use R to compute the occurrence count (histogram) for an array of values in the range [0,10): histogram :: Acc (Vector Int) -> Acc (Vector Int) histogram xs = let zeros = fill (constant (Z:.10)) 0 ones = fill (shape xs) 1 in permute (+) zeros (\ix -> index1 (xs!ix)) onesElet xs = fromList (Z :. 20) [0,0,1,2,1,1,2,4,8,3,4,9,8,3,2,5,5,3,1,2]histogram (use xs)&Vector (Z :. 10) [2,4,4,3,2,2,0,0,2,1] Note:Regarding array fusion: The Q operation will always be evaluated; it can not be fused into a later step.Since the index permutation function might not cover all positions in the output array (the function is not surjective), the array of default values must be evaluated. However, other operations may fuse into this.CThe array of source values can fuse into the permutation operation.:Generalised backward permutation operation (array gather).Backward permutation specified by a function mapping indices in the destination array to indices in the source array. Elements of the output array are thus generated by reading from the corresponding index in the source array.)For example, backpermute can be used to CF a matrix; at every index Z:.y:.xa in the result array, we get the value at that index by reading from the source array at index Z:.x:.y: Aswap :: Exp DIM2 -> Exp DIM2 swap = lift1 $ \(Z:.y:.x) -> Z:.x:.y#let mat = fromList (Z:.5:.10) [0..]matMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]let mat' = use mat)backpermute (swap (shape mat')) swap mat' Matrix (Z :. 10 :. 5) [ 0, 10, 20, 30, 40, 1, 11, 21, 31, 41, 2, 12, 22, 32, 42, 3, 13, 23, 33, 43, 4, 14, 24, 34, 44, 5, 15, 25, 35, 45, 6, 16, 26, 36, 46, 7, 17, 27, 37, 47, 8, 18, 28, 38, 48, 9, 19, 29, 39, 49],Map a stencil over an array. In contrast to 1, the domain of a stencil function is an entire  neighbourhoodR of each array element. Neighbourhoods are sub-arrays centred around a focal point. They are not necessarily rectangular, but they are symmetric and have an extent of at least three along each axis. Due to the symmetry requirement the extent is necessarily odd. The focal point is the array position that is determined by the stencil.For those array positions where the neighbourhood extends past the boundaries of the source array, a boundary condition determines the contents of the out-of-bounds neighbourhood positions.Stencil neighbourhoods are specified via nested tuples, where the nesting depth is equal to the dimensionality of the array. For example, a 3x1 stencil for a one-dimensional array: ,s31 :: Stencil3 a -> Exp a s31 (l,c,r) = ... ...where c( is the focal point of the stencil, and l and r represent the elements to the left and right of the focal point, respectively. Similarly, a 3x3 stencil for a two-dimensional array: )s33 :: Stencil3x3 a -> Exp a s33 ((_,t,_),(l,c,r) ,(_,b,_)) = ... ...where c is again the focal point and t, b, l and r are the elements to the top, bottom, left, and right of the focal point, respectively (the diagonal elements have been elided).+For example, the following computes a 5x5  +https://en.wikipedia.org/wiki/Gaussian_blur Gaussian blur" as a separable 2-pass operation. type Stencil5x1 a = (Stencil3 a, Stencil5 a, Stencil3 a) type Stencil1x5 a = (Stencil3 a, Stencil3 a, Stencil3 a, Stencil3 a, Stencil3 a) convolve5x1 :: Num a => [Exp a] -> Stencil5x1 a -> Exp a convolve5x1 kernel (_, (a,b,c,d,e), _) = Prelude.sum $ Prelude.zipWith (*) kernel [a,b,c,d,e] convolve1x5 :: Num a => [Exp a] -> Stencil1x5 a -> Exp a convolve1x5 kernel ((_,a,_), (_,b,_), (_,c,_), (_,d,_), (_,e,_)) = Prelude.sum $ Prelude.zipWith (*) kernel [a,b,c,d,e] gaussian = [0.06136,0.24477,0.38774,0.24477,0.06136] blur :: Num a => Acc (Array DIM2 a) -> Acc (Array DIM2 a) blur = stencil (convolve5x1 gaussian) Clamp . stencil (convolve1x5 gaussian) ClampMap a binary stencil of an array. The extent of the resulting array is the intersection of the extents of the two source arrays. This is the stencil equivalent of .Call a foreign array function.The form the first argument takes is dependent on the backend being targeted. Note that the foreign function only has access to the input array(s) passed in as its argument.In case the operation is being executed on a backend which does not support this foreign implementation, the fallback implementation is used instead, which itself could be a foreign implementation for a (presumably) different backend, or an implementation of pure Accelerate. In this way, multiple foreign implementations can be supplied, and will be tested for suitability against the target backend in sequence.For an example see the  2https://hackage.haskell.org/package/accelerate-fftaccelerate-fft package.!Call a foreign scalar expression.The form of the first argument is dependent on the backend being targeted. Note that the foreign function only has access to the input element(s) passed in as its first argument.As with , the fallback implementation itself may be a (sequence of) foreign implementation(s) for a different backend(s), or implemented purely in Accelerate.Pipelining of two array computations. The first argument will be fully evaluated before being passed to the second computation. This can be used to prevent the argument being fused into the function, for example.Denotationally, we have X(acc1 >-> acc2) arrs = let tmp = acc1 arrs in tmp `seq` acc2 tmp&An array-level if-then-else construct.An array-level z construct. Continue to apply the given function, starting with the initial value, until the test function evaluates to .&Get the innermost dimension of a shape,Get all but the innermost element of a shapeSMap a multi-dimensional index into a linear, row-major representation of an array. Inverse of Intersection of two shapesUnion of two shapes&A scalar-level if-then-else construct.~While construct. Continue to apply the given function, starting with the initial value, until the test function evaluates to .dMultidimensional array indexing. Extract the value from an array at the specified zero-based index.#let mat = fromList (Z:.5:.10) [0..]matMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49] mat ! Z:.1:.212Extract the value from an array at the specified linear index. Multidimensional arrays in Accelerate are stored in row-major order with zero-based indexing.#let mat = fromList (Z:.5:.10) [0..]matMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49] mat !! 1212'Extract the shape (extent) of an array.#The number of elements in the arrayIThe number of elements that would be held by an array of the given shape. is the same as flip ().Determine if a number is evenDetermine if a number is odd x y$ is the non-negative factor of both x and y' of which every common factor of both x and y is also a factor; for example: gcd 4 2 = 2gcd (-4) 6 = 2 gcd 0 4 = 4 gcd 0 0 = 0PThat is, the common divisor that is "greatest" in the divisibility preordering. x y, is the smallest positive integer that both x and y divide./Raise a number to a non-negative integral power#Raise a number to an integral powerConvert a character to an  . Convert an   into a character.Convert a Boolean value to an  , where  turns into '0' and  into '1'.ZReinterpret a value as another type. The two representations must have the same bit size.KMagic value identifying elements that are ignored in a forward permutation.Dcombination functionarray of default valuesindex permutation function%array of source values to be permutedshape of the result arrayindex permutation function source arraystencil functionboundary condition source arraydestination arraybinary stencil functionboundary condition #1source array #1boundary condition #2source array #2destination array if-condition then-array else-array#keep evaluating while this returns function to apply initial valueextent of the arrayindex to remap conditionthen-expressionelse-expression#keep evaluating while this returns function to apply initial valueMSWTUVD19 9 88H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None $%&*:T6Return the number of bits in the type of the argument.zCount the number of zero bits preceding the most significant set bit. This can be used to compute a base-2 logarithm via: 6logBase2 x = finiteBitSize x - 1 - countLeadingZeros xUCount the number of zero bits following the least significant set bit. The related  +http://en.wikipedia.org/wiki/Find_first_setfind-first-set operation' can be expressed in terms of this as: )findFirstSet x = 1 + countTrailingZeros xThe  class defines bitwise operations over integral scalar expression types. As usual, bits are numbered from zero, with zero being the least significant bit. Bitwise "and" Bitwise "or" Bitwise "xor" Reverse all bits in the argument x i shifts x left by i bits if i is positive, or right by -ix bits otherwise. Right shifts perform sign extension on signed number types; i.e. they fill the top bits with 1 if the x# is negative and with 0 otherwise. x i rotates x left by i bits if i is positive, or right by -i bits otherwise.The value with all bits unsetbit i is a value with the i$th bit set and all other bits clear. x `setBit` i is the same as  x .|. bit ix `clearBit` i is the same as x .&. complement (bit i)x `complementBit` i is the same as  x `xor` bit iReturn  if the nth bit of the argument is 1Return " if the argument is a signed type.VShift the argument left by the specified number of bits (which must be non-negative).Shift the argument left by the specified number of bits. The result is undefined for negative shift amounts and shift amounts greater or equal to the .]Shift the first argument right by the specified number of bits (which must be non-negative).cRight shifts perform sign extension on signed number types; i.e. they fill the top bits with 1 if x" is negative and with 0 otherwise. Shift the first argument right by the specified number of bits. The result is undefined for negative shift amounts and shift amounts greater or equal to the . WRotate the argument left by the specified number of bits (which must be non-negative). WRotate the argument right by the specified number of bits (which must be non-negative). sReturn the number of set bits in the argument. This number is known as the population count or the Hamming weight.Q      !"#$%&'()*+,-./012        :      !"#$%&'()*+,-./012 7568888 8 8GH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None 9:;<=DQR 3DA limited subset of types which can be lifted, can also be unlifted.4Unlift the outermost constructor through the surface type. This is only possible if the constructor is fully determined by its type - i.e., it is a singleton.5The class of types e which can be lifted into c.6jAn associated-type (i.e. a type-level function) that strips all instances of surface type constructors c from the input type e.For example, the tuple types (Exp Int, Int) and (Int, Exp Int)V have the same "Plain" representation. That is, the following type equality holds: 7Plain (Exp Int, Int) ~ (Int,Int) ~ Plain (Int, Exp Int)7)Lift the given value into a surface type c --- either  for scalar expressions or J for array computations. The value may already contain subexpressions in c.8Lift a unary function into .9Lift a binary function into .:Lift a ternary function into .;;Lift a unary function to a computation over rank-1 indices.<<Lift a binary function to a computation over rank-1 indices.==Lift a ternary function to a computation over rank-1 indices.m3456789:;<=      !"#$% 3456789:;<=j3456789:;<=      !"#$%[2015..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None*9:;<=DRT>.The non-negative magnitude of a complex number?,The phase of a complex number, in the range (-@, @]2. If the magnitude is zero, then so is the phase.@ The function @ takes a complex number and returns a (magnitude, phase) pair in canonical form: the magnitude is non-negative, and the phase in the range (-@, @]1; if the magnitude is zero, then so is the phase.ACForm a complex number from polar components of magnitude and phase.BB t# is a complex value with magnitude 1 and phase t (modulo 2*@).C(Return the real part of a complex numberD-Return the imaginary part of a complex numberE<Return the complex conjugate of a complex number, defined as conjugate(Z) = X - iY>?@ABCDEFGHIJKLMN >?@ABCDE CDAB@>?E>?@ABCDEFGHIJKLMNCn[2009..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonell [2010..2011] Ben LeverBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None)*9:;<=DMQRTeO For use with -XRebindableSyntax, this class provides Q( lifted to both scalar and array types.R Pair each element with its indexS;Apply a function to every element of an array and its indexT7Zip three arrays with the given function, analogous to .U6Zip four arrays with the given function, analogous to .V6Zip five arrays with the given function, analogous to .W5Zip six arrays with the given function, analogous to .X7Zip seven arrays with the given function, analogous to .Y7Zip eight arrays with the given function, analogous to .Z6Zip nine arrays with the given function, analogous to .[@Zip two arrays with a function that also takes the element index\RZip three arrays with a function that also takes the element index, analogous to [.]YZip four arrays with the given function that also takes the element index, analogous to .^YZip five arrays with the given function that also takes the element index, analogous to ._XZip six arrays with the given function that also takes the element index, analogous to .`ZZip seven arrays with the given function that also takes the element index, analogous to .aZZip eight arrays with the given function that also takes the element index, analogous to .bYZip nine arrays with the given function that also takes the element index, analogous to .cuCombine the elements of two arrays pairwise. The shape of the result is the intersection of the two argument shapes.dCTake three arrays and return an array of triples, analogous to zip.eETake four arrays and return an array of quadruples, analogous to zip.fFTake five arrays and return an array of five-tuples, analogous to zip.gDTake six arrays and return an array of six-tuples, analogous to zip.hHTake seven arrays and return an array of seven-tuples, analogous to zip.iHTake seven arrays and return an array of seven-tuples, analogous to zip.jHTake seven arrays and return an array of seven-tuples, analogous to zip.kThe converse of cN, but the shape of the two results is identical to the shape of the argument.-If the argument array is manifest in memory, k is a NOP.lETake an array of triples and return three arrays, analogous to unzip.mGTake an array of quadruples and return four arrays, analogous to unzip.nETake an array of 5-tuples and return five arrays, analogous to unzip.oDTake an array of 6-tuples and return six arrays, analogous to unzip.pFTake an array of 7-tuples and return seven arrays, analogous to unzip.qFTake an array of 8-tuples and return eight arrays, analogous to unzip.rFTake an array of 8-tuples and return eight arrays, analogous to unzip.seReduction of an array of arbitrary rank to a single scalar value. The first argument needs to be an  associativet function to enable efficient parallel implementation. The initial element does not need to be an identity element. let vec = fromList (Z:.10) [0..]foldAll (+) 42 (use vec) Scalar Z [87]#let mat = fromList (Z:.5:.10) [0..]foldAll (+) 0 (use mat)Scalar Z [1225]t Variant of ss that requires the reduced array to be non-empty and doesn't need an default value. The first argument must be an  associative function.u)Check if all elements satisfy a predicatev,Check if any element satisfies the predicatewCheck if all elements are xCheck if any element is yCompute the sum of elementsz#Compute the product of the elements{CYield the minimum element of an array. The array must not be empty.|CYield the maximum element of an array. The array must not be empty.}4Left-to-right prescan (aka exclusive scan). As for scan!, the first argument must be an  associative# function. Denotationally, we have 'prescanl f e = Prelude.fst . scanl' f e"let vec = fromList (Z:.10) [1..10]prescanl (+) 0 (use vec)+Vector (Z :. 10) [0,0,1,3,6,10,15,21,28,36]~%Left-to-right postscan, a variant of ! with an initial value. As with 7, the array must not be empty. Denotationally, we have: &postscanl f e = map (e `f`) . scanl1 f"let vec = fromList (Z:.10) [1..10]postscanl (+) 42 (use vec)0Vector (Z :. 10) [42,43,45,48,52,57,63,70,78,87]4Right-to-left prescan (aka exclusive scan). As for scan!, the first argument must be an  associative# function. Denotationally, we have 'prescanr f e = Prelude.fst . scanr' f e%Right-to-left postscan, a variant of 0 with an initial value. Denotationally, we have &postscanr f e = map (e `f`) . scanr1 fSegmented version of  along the innermost dimension of an array. The innermost dimension must have at least as many elements as the sum of the segment descriptor.#let seg = fromList (Z:.4) [1,4,0,3]segVector (Z :. 4) [1,4,0,3]#let mat = fromList (Z:.5:.10) [0..]matMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]"scanlSeg (+) 0 (use mat) (use seg)Matrix (Z :. 5 :. 12)2 [ 0, 0, 0, 1, 3, 6, 10, 0, 0, 5, 11, 18,2 0, 10, 0, 11, 23, 36, 50, 0, 0, 15, 31, 48,2 0, 20, 0, 21, 43, 66, 90, 0, 0, 25, 51, 78,2 0, 30, 0, 31, 63, 96, 130, 0, 0, 35, 71, 108,2 0, 40, 0, 41, 83, 126, 170, 0, 0, 45, 91, 138]Segmented version of  along the innermost dimension of an array. The innermost dimension must have at least as many elements as the sum of the segment descriptor.The first element of the resulting tuple is a vector of scanned values. The second element is a vector of segment scan totals and has the same size as the segment vector.#let seg = fromList (Z:.4) [1,4,0,3]segVector (Z :. 4) [1,4,0,3]#let mat = fromList (Z:.5:.10) [0..]matMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]4let (res,sums) = scanl'Seg (+) 0 (use mat) (use seg)resMatrix (Z :. 5 :. 8)! [ 0, 0, 1, 3, 6, 0, 5, 11,! 0, 0, 11, 23, 36, 0, 15, 31,! 0, 0, 21, 43, 66, 0, 25, 51,! 0, 0, 31, 63, 96, 0, 35, 71,! 0, 0, 41, 83, 126, 0, 45, 91]sumsMatrix (Z :. 5 :. 4) [ 0, 10, 0, 18, 10, 50, 0, 48, 20, 90, 0, 78, 30, 130, 0, 108, 40, 170, 0, 138]Segmented version of  along the innermost dimension.As with F, the total number of elements considered, in this case given by the ye of segment descriptor, must not be zero. The input vector must contain at least this many elements.Zero length segments are allowed, and the behaviour is as if those entries were not present in the segment descriptor; that is: ;scanl1Seg f xs [n,0,0] == scanl1Seg f xs [n] where n /= 0#let seg = fromList (Z:.4) [1,4,0,3]segVector (Z :. 4) [1,4,0,3]#let mat = fromList (Z:.5:.10) [0..]matMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]!scanl1Seg (+) (use mat) (use seg)Matrix (Z :. 5 :. 8)& [ 0, 1, 3, 6, 10, 5, 11, 18,& 10, 11, 23, 36, 50, 15, 31, 48,& 20, 21, 43, 66, 90, 25, 51, 78,& 30, 31, 63, 96, 130, 35, 71, 108,& 40, 41, 83, 126, 170, 45, 91, 138]Segmented version of }.Segmented version of ~.Segmented version of  along the innermost dimension of an array. The innermost dimension must have at least as many elements as the sum of the segment descriptor.#let seg = fromList (Z:.4) [1,4,0,3]segVector (Z :. 4) [1,4,0,3]#let mat = fromList (Z:.5:.10) [0..]matMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]"scanrSeg (+) 0 (use mat) (use seg)Matrix (Z :. 5 :. 12)2 [ 2, 0, 18, 15, 11, 6, 0, 0, 24, 17, 9, 0,2 12, 0, 58, 45, 31, 16, 0, 0, 54, 37, 19, 0,2 22, 0, 98, 75, 51, 26, 0, 0, 84, 57, 29, 0,2 32, 0, 138, 105, 71, 36, 0, 0, 114, 77, 39, 0,2 42, 0, 178, 135, 91, 46, 0, 0, 144, 97, 49, 0]Segmented version of .#let seg = fromList (Z:.4) [1,4,0,3]segVector (Z :. 4) [1,4,0,3]#let mat = fromList (Z:.5:.10) [0..]matMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]4let (res,sums) = scanr'Seg (+) 0 (use mat) (use seg)resMatrix (Z :. 5 :. 8)! [ 0, 15, 11, 6, 0, 17, 9, 0,! 0, 45, 31, 16, 0, 37, 19, 0,! 0, 75, 51, 26, 0, 57, 29, 0,! 0, 105, 71, 36, 0, 77, 39, 0,! 0, 135, 91, 46, 0, 97, 49, 0]sumsMatrix (Z :. 5 :. 4) [ 2, 18, 0, 24, 12, 58, 0, 54, 22, 98, 0, 84, 32, 138, 0, 114, 42, 178, 0, 144]Segmented version of .#let seg = fromList (Z:.4) [1,4,0,3]segVector (Z :. 4) [1,4,0,3]#let mat = fromList (Z:.5:.10) [0..]matMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]!scanr1Seg (+) (use mat) (use seg)Matrix (Z :. 5 :. 8)& [ 0, 10, 9, 7, 4, 18, 13, 7,& 10, 50, 39, 27, 14, 48, 33, 17,& 20, 90, 69, 47, 24, 78, 53, 27,& 30, 130, 99, 67, 34, 108, 73, 37,& 40, 170, 129, 87, 44, 138, 93, 47]Segmented version of .Segmented version of .&=Compute head flags vector from segment vector for left-scans. The vector will be full of zeros in the body of a segment, and non-zero otherwise. The "flag" value, if greater than one, indicates that several empty segments are represented by this single flag entry. This is additional data is used by exclusive segmented scan.'~Compute tail flags vector from segment vector for right-scans. That is, the flag is placed at the last place in each segment.(Construct a segmented version of a function from a non-segmented version. The segmented apply operates on a head-flag value tuple, and follows the procedure of Sengupta et. al.)AIndex construction and destruction generalised to integral types.%We generalise the segment descriptor to integral types because some architectures, such as GPUs, have poor performance for 64-bit types. So, there is a tension between performance and requiring 64-bit indices for some applications, and we would not like to restrict ourselves to either one.As we don't yet support non-Int dimensions in shapes, we will need to convert back to concrete Int. However, don't put these generalised forms into the base library, because it results in too many ambiguity errors.WFlatten the given array of arbitrary dimension into a one-dimensional vector. As with ", this operation performs no work.6Create an array where all elements are the same value.9Create an array of the given shape containing the values x, x+1, etc. (in row-major order).3enumFromN (constant (Z:.5:.10)) 0 :: Array DIM2 IntMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]9Create an array of the given shape containing the values x, x+y, x+y+y etc. (in row-major order).=enumFromStepN (constant (Z:.5:.10)) 0 0.5 :: Array DIM2 FloatMatrix (Z :. 5 :. 10)? [ 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5,? 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5,? 10.0, 10.5, 11.0, 11.5, 12.0, 12.5, 13.0, 13.5, 14.0, 14.5,? 15.0, 15.5, 16.0, 16.5, 17.0, 17.5, 18.0, 18.5, 19.0, 19.5,? 20.0, 20.5, 21.0, 21.5, 22.0, 22.5, 23.0, 23.5, 24.0, 24.5]Concatenate innermost component of two arrays. The extent of the lower dimensional component is the intersection of the two arrays."let m1 = fromList (Z:.5:.10) [0..]m1Matrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]"let m2 = fromList (Z:.10:.3) [0..]m2 Matrix (Z :. 10 :. 3) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]use m1 ++ use m2Matrix (Z :. 5 :. 13)7 [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2,7 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 3, 4, 5,7 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 6, 7, 8,7 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 9, 10, 11,7 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 12, 13, 14]Drop elements that do not satisfy the predicate. Returns the elements which pass the predicate, together with a segment descriptor indicating how many elements along each outer dimension were valid.2let vec = fromList (Z :. 10) [1..10] :: Vector Intvec'Vector (Z :. 10) [1,2,3,4,5,6,7,8,9,10]filter even (use vec),(Vector (Z :. 5) [2,4,6,8,10], Scalar Z [5])let mat = fromList (Z :. 4 :. 10) [1,2,3,4,5,6,7,8,9,10,1,1,1,1,1,2,2,2,2,2,2,4,6,8,10,12,14,16,18,20,1,3,5,7,9,11,13,15,17,19] :: Array DIM2 IntmatMatrix (Z :. 4 :. 10)' [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,' 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,' 2, 4, 6, 8, 10, 12, 14, 16, 18, 20,' 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]filter odd (use mat)](Vector (Z :. 20) [1,3,5,7,9,1,1,1,1,1,1,3,5,7,9,11,13,15,17,19], Vector (Z :. 4) [5,5,0,10])KGather elements from a source array by reading values at the given indices./let input = fromList (Z:.9) [1,9,6,4,4,2,0,1,2])let from = fromList (Z:.6) [1,3,7,2,5,3]gather (use from) (use input)Vector (Z :. 6) [9,4,1,6,2,4]*bConditionally copy elements from source array to destination array according to an index mapping.In addition, the maskx vector and associated predication function specifies whether the element is copied or a default value is used instead..let defaults = fromList (Z :. 6) [6,6,6,6,6,6].let from = fromList (Z :. 6) [1,3,7,2,5,3].let mask = fromList (Z :. 6) [3,4,9,2,7,5]4let input = fromList (Z :. 9) [1,9,6,4,4,2,0,1,2]?gatherIf (use from) (use mask) (> 4) (use defaults) (use input)Vector (Z :. 6) [6,6,1,6,2,4]yOverwrite elements of the destination by scattering the values of the source array according to the given index mapping.bNote that if the destination index appears more than once in the mapping the result is undefined.+let to = fromList (Z :. 6) [1,3,7,2,5,8]-let input = fromList (Z :. 7) [1,9,6,4,4,2,5]8scatter (use to) (fill (constant (Z:.10)) 0) (use input)&Vector (Z :. 10) [0,1,4,9,0,4,0,6,2,0]+Conditionally overwrite elements of the destination by scattering values of the source array according to a given index mapping, whenever the masking function resolves to .bNote that if the destination index appears more than once in the mapping the result is undefined.+let to = fromList (Z :. 6) [1,3,7,2,5,8]+let mask = fromList (Z :. 6) [3,4,9,2,7,5]-let input = fromList (Z :. 7) [1,9,6,4,4,2,5]KscatterIf (use to) (use mask) (> 4) (fill (constant (Z:.10)) 0) (use input)&Vector (Z :. 10) [0,0,0,0,0,4,0,6,2,0]!Reverse the elements of a vector.+Transpose the rows and columns of a matrix.Yield the first nY elements in the innermost dimension of the array (plus all lower dimensional elements).#let mat = fromList (Z:.5:.10) [0..]matMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]take 5 (use mat)Matrix (Z :. 5 :. 5) [ 0, 1, 2, 3, 4, 10, 11, 12, 13, 14, 20, 21, 22, 23, 24, 30, 31, 32, 33, 34, 40, 41, 42, 43, 44]Yield all but the first n\ elements along the innermost dimension of the array (plus all lower dimensional elements).#let mat = fromList (Z:.5:.10) [0..]matMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]drop 7 (use mat)Matrix (Z :. 5 :. 3) [ 7, 8, 9, 17, 18, 19, 27, 28, 29, 37, 38, 39, 47, 48, 49]HYield all but the elements in the last index of the innermost dimension.#let mat = fromList (Z:.5:.10) [0..]matMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]init (use mat)Matrix (Z :. 5 :. 9)' [ 0, 1, 2, 3, 4, 5, 6, 7, 8,' 10, 11, 12, 13, 14, 15, 16, 17, 18,' 20, 21, 22, 23, 24, 25, 26, 27, 28,' 30, 31, 32, 33, 34, 35, 36, 37, 38,' 40, 41, 42, 43, 44, 45, 46, 47, 48]vYield all but the first element along the innermost dimension of an array. The innermost dimension must not be empty.#let mat = fromList (Z:.5:.10) [0..]matMatrix (Z :. 5 :. 10)+ [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]tail (use mat)Matrix (Z :. 5 :. 9)' [ 1, 2, 3, 4, 5, 6, 7, 8, 9,' 11, 12, 13, 14, 15, 16, 17, 18, 19,' 21, 22, 23, 24, 25, 26, 27, 28, 29,' 31, 32, 33, 34, 35, 36, 37, 38, 39,' 41, 42, 43, 44, 45, 46, 47, 48, 49]TYield a slit (slice) of the innermost indices of an array. Denotationally, we have: slit i n = take n . drop iForce an array expression to be evaluated, preventing it from fusing with other operations. Forcing operations to be computed to memory, rather than being fused into their consuming function, can sometimes improve performance. For example, computing a matrix  could provide better memory locality for the subsequent operation. Preventing fusion to split large operations into several simpler steps could also help by reducing register pressure.Preventing fusion also means that the individual operations are available to be executed concurrently with other kernels. In particular, consider using this if you have a series of operations that are compute bound rather than memory bound.Here is the synthetic example: Eloop :: Exp Int -> Exp Int loop ticks = let clockRate = 900000 -- kHz in while (\i -> i < clockRate * ticks) (+1) 0 test :: Acc (Vector Int) test = zip3 (compute $ map loop (use $ fromList (Z:.1) [10])) (compute $ map loop (use $ fromList (Z:.1) [10])) (compute $ map loop (use $ fromList (Z:.1) [10])) Without the use of , the operations are fused together and the three long-running loops are executed sequentially in a single kernel. Instead, the individual operations can now be executed concurrently, potentially reducing overall runtime.Infix version of  . If the predicate evaluates to A, the first component of the tuple is returned, else the second. See also: Q.An infix version of  . If the predicate evaluates to A, the first component of the tuple is returned, else the second. See also: Q.A case-like control structure3Repeatedly apply a function a fixed number of times,Reduce along an innermost slice of an array  sequentiallyV, by applying a binary operator to a starting value and the array from left to right.-Extract the first component of a scalar pair.-Extract the first component of an array pair..Extract the second component of a scalar pair.-Extract the second component of an array pair5Converts an uncurried function to a curried function.3Converts a curried function to a function on pairs.!The one index for a rank-0 array.Turn an  . expression into a rank-1 indexing expression.*Turn a rank-1 indexing expression into an   expression.)Creates a rank-2 index from two Exp Int`s6Destructs a rank-2 index to an Exp tuple of two Int`s.*Create a rank-3 index from three Exp Int`s2Destruct a rank-3 index into an Exp tuple of Int`s)Extract the element of a singleton array. the xs == xs ! ZTest whether an array is empty.Get the length of a vector.kOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~&'()x: starty: step'index of source at each index to gather source values*source indices to gather from mask vectorpredicate functiondefault values source values#destination indices to scatter intodefault values source values+#destination indices to scatter into mask vectorpredicate functiondefault values source values case subjectlist of cases to attempt default value,-./n3456789:;<=OPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~*+iOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~&'()*+,-./500HH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%&*9;DMOQRT0OReplace the first variable with the given expression. The environment shrinks.1Replace an expression that uses the top environment variable with another. The result of the first is let bound into the second.2Composition of unary functions.K3456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUV012WXYZ[\]^_`abcdefghijklmnopqrstuvwxyz:CDEFGHIJKLMONPQRS012WXYZ53456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUV012WXYZ[\]^_`abcdefghijklmnopqrstuvwxyz1 2 IH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None!"%&*9;DMOQRT{hReplace all occurrences of the first variable with the given array expression. The environment shrinks.=|}~{2FG|}~{+|}~{Jc[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%&OTCReify the dimensionality of the result type of an array computationLReify dimensionality of a computation parameterised over a recursive closure<Reify dimensionality of a scalar expression yielding a shapeKH[2015..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None!"$%&9;LMOT5Generate a dependency graph for the given computation1Generate a dependency graph for an array function#Lc[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None?Display simplifier statistics. The counts are reset afterwards.Write a representation of the given input (a closed array expression or function) to file in Graphviz dot format in the temporary directory.@      !"#$%&'()*+,-./056789LMNOPQRWZcghijklmM[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonell [2015..2017] Robert Clifton-EverestBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneCreate a fresh nursery.tWhen the nursery is garbage collected, the provided function will be run on each value to free the retained memory.*Look for an entry with the requested size.Add an entry to the nursery#Delete all entries from the nursery1The total number of bytes retained by the nursery  N[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonell [2015..2017] Robert Clifton-EverestBSD32Robert Clifton-Everest <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None$%&*BIMOT :An untyped reference to an array, similar to a StableName.5Create a new memory table from host to remote arrays.$The function supplied should be the  for the remote pointers being stored. This function will be called by the GC, which typically runs on a different thread. Unlike the  in <,, this function cannot depend on any state.ELook for the remote pointer corresponding to a given host-side array.jAllocate a new device array to be associated with the given host-side array. This may not always use the  provided by the < instance. In order to reduce the number of raw allocations, previously allocated remote arrays will be re-used. In the event that the remote memory is exhausted, e is returned.Deallocate the device array associated with the given host-side array. Typically this should only be called in very specific circumstances.Deallocate the device array associated with the given StableArray. This is useful for other memory managers built on top of the memory table.Record an association between a host-side array and a remote memory area that was not allocated by accelerate. The remote memory will NOT be re-used once the host-side array is garbage collected.=This typically only has use for backends that provide an FFI.gInitiate garbage collection and mark any arrays that no longer have host-side equivalents as reusable.Call H on all arrays that are not currently associated with host-side arrays. Initiate garbage collection and G any remote arrays that no longer have matching host-side equivalents. Make a new .AMake a weak pointer using an array as a key. Unlike the standard /, this guarantees finalisers won't fire early.                  O{[2015..2017] Manuel M T Chakravarty, Gabriele Keller, Robert Clifton-Everest [2016..2017] Trevor L. McDonellBSD31Robert Clifton-Everest <robertce@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None %&(*MOT A Task represents a process executing asynchronously that can be polled for its status. This is necessary for backends that work asynchronously (i.e. the CUDA backend). If a backend is synchronous, the () instance can be used. (Returns true when the task has finished. 5Create a new memory cache from host to remote arrays.$The function supplied should be the   for the remote pointers being stored. This function will be called by the GC, which typically runs on a different thread. Unlike the   in <,, this function cannot depend on any state. `Perform some action that requires the remote pointer corresponding to the given array. Returns e if the array have NEVER been in the cache. If the array was previously in the cache, but was evicted due to its age, then the array will be copied back from host memory.tThe continuation passed as the third argument needs to obey some precise properties. As with all bracketed functions, the supplied remote pointer must not leak out of the function, as it is only guaranteed to be valid within it. If it is required that it does leak (e.g. the backend is uses concurrency to interleave execution of different parts of the program), then  w on the returned task should not return true until it is guaranteed there are no more accesses of the remote pointer. Allocate a new device array to be associated with the given host-side array. This has similar behaviour to malloc in Data.Array.Accelerate.Array.Memory.Table but also will copy remote arrays back to main memory in order to make space.The third argument indicates that the array should be considered frozen. That is to say the array arrays contents will never change. In the event that the array has to be evicted from the remote memory, the copy already residing in host memory should be considered valid.`If malloc is called on an array that is already contained within the cache, it becomes a no-op. On return, 5 indicates that we allocated some remote memory, and $ indicates that we did not need to. Deallocate the device array associated with the given host-side array. Typically this should only be called in very specific circumstances. This operation is not thread-safe. Record an association between a host-side array and a remote memory area that was not allocated by accelerate. The remote memory will NOT be re-used once the host-side array is garbage collected.=This typically only has use for backends that provide an FFI.  Initiate garbage collection and  G any remote arrays that no longer have matching host-side equivalents.              True if host array is frozen.    !  " # $ % & ' ( )                        !  " # $ % & ' ( )P{[2015..2017] Manuel M T Chakravarty, Gabriele Keller, Robert Clifton-Everest [2016..2017] Trevor L. McDonellBSD31Robert Clifton-Everest <robertce@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None<=>?@ABCDE     Q[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonell [2013..2017] Robert Clifton-EverestBSD3-Manuel M T Chakravarty <chak@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%&/09;DMQRT *'Recover sharing of array computations ? +'Recover sharing of scalar expressions ? ,*Recover sharing of sequence computations ? -4Always float array computations out of expressions ? .bConvert a closed array expression to de Bruijn form while also incorporating sharing information. /\Convert a closed function over array computations, while incorporating sharing information. 0aConvert an open array expression to de Bruijn form while also incorporating sharing information. 1Convert an array expression with given array environment layout and sharing information into de Bruijn form while recovering sharing at the same time (by introducing appropriate let bindings). The latter implements the third phase of sharing recovery.The sharing environment env keeps track of all currently bound sharing variables, keeping them in reverse chronological order (outermost variable is at the end of the list). 2Convert a boundary condition 3\Convert a closed scalar function to de Bruijn form while incorporating sharing information.The current design requires all free variables to be bound at the outermost level --- we have no general apply term, and so lambdas are always outermost. In higher-order abstract syntax, this represents an n-ary, polyvariadic function. 4^Convert a closed scalar expression to de Bruijn form while incorporating sharing information. 5Convert an open expression with given environment layouts and sharing information into de Bruijn form while recovering sharing at the same time (by introducing appropriate let bindings). The latter implements the third phase of sharing recovery.The sharing environments env and aenv keep track of all currently bound sharing variables, keeping them in reverse chronological order (outermost variable is at the end of the list). 6Convert a tuple expression 7Convert a unary functions 8Convert a binary functions 9 Convert a unary stencil function :!Convert a binary stencil function ;Recover sharing information and annotate the HOAS AST with variable and let binding annotations. The first argument determines whether array computations are floated out of expressions irrespective of whether they are shared or not   implies floating them out.Also returns the  < s of all 8M leaves in environment order  they represent the free variables of the AST.NB: Strictly speaking, this function is not deterministic, as it uses stable pointers to determine the sharing of subterms. The stable pointer API does not guarantee its completeness; i.e., it may miss some equalities, which implies that we may fail to discover some sharing. However, sharing does not affect the denotational meaning of an array computation; hence, we do not compromise denotational correctness..There is one caveat: We currently rely on the 8 and ! leaves representing free variables to be shared if any of them is used more than once. If one is duplicated, the environment for de Bruijn conversion will have a duplicate entry, and hence, be of the wrong size, which is fatal. (The 'buildInitialEnv*'" functions will already bail out.) = > ? @ A B C D E F G H I J K L M N O < P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l * + , - m n o p .'recover sharing of array computations ?'recover sharing of scalar expressions ?*recover sharing of sequence computations ?3always float array computations out of expressions? / 0 1 q r 2 s t 3 4'recover sharing of scalar expressions ?expression to be converted u 5 6 7 8 9 : v w x y z { | } ~  ;  b c e f . / 3 4h = > ? @ A B C D E F G H I J K L M N O < P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l * + , - m n o p . / 0 1 q r 2 s t 3 4 u 5 6 7 8 9 : v w x y z { | } ~  ; Rc[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%&9;T Show instances ---------------       SH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None $%&LMOQRTR       R      TH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%&T      UH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None$%&MOT                        VH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None!"$%&9:;MQRT          ! " # $ % & ' ( ) * + , - . / 0 1 2 3            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 ,1 -4 .6Ww[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonell [2014..2014] Frederik M. MadsenBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None$%&*-9:;MOQRT 4Apply the fusion transformation to the AST to combine and simplify terms. This converts terms into the internal delayed array representation and merges adjacent producer/producer terms. Using the reduced internal form limits the number of combinations that need to be considered. 59Apply the fusion transformation to a closed de Bruijn AST 6@Apply the fusion transformation to a function of array arguments 7GApply the fusion transformation to an AST. This consists of two phases: A bottom-up traversal that converts nodes into the internal delayed representation, merging adjacent producer/producer pairs.iA top-down traversal that makes the representation of fused consumer/producer pairs explicit as a & of manifest and delayed nodes.TLM: Note that there really is no ambiguity as to which state an array will be in following this process: an array will be either delayed or manifest, and the two helper functions are even named as such! We should encode this property in the type somehow...4 8 9 : ; < = > 4 5 6 ? 7 @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g 5 60 8 9 : ; < = > 4 5 6 ? 7 @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f gXH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None!"9:; h&Recover sharing of array computations? i&Recover sharing of scalar expressions? j)Recover sharing of sequence computations? knAre array computations floated out of expressions irrespective of whether they are shared or not? Requires  h. lmFuse array computations? This also implies simplifying scalar expressions. NOTE: currently always enabled. m9Convert segment length arrays into segment offset arrays? nsThe default method of converting from HOAS to de Bruijn; incorporating sharing recovery and fusion optimisation. ouConvert a closed array expression to de Bruijn form while also incorporating sharing observation and array fusion. pgConvert a unary function over array computations, incorporating sharing observation and array fusion qZConvert a closed scalar expression, incorporating sharing observation and optimisation. rWConvert closed scalar functions, incorporating sharing observation and optimisation. s t h i j k l m n u o v p w q r x y z { | }7:CDEFGHIJKLMONPQRS012WXYZ s t h i j k l m n o v p w s t h i j k l m n u o v p w q r x y z { | }Yc[2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None %&DMORT ~KDetermine the type of an expressions ------------------------------------- 1Determine an array type ------------------------#Reify the element type of an array. =Reify the element type of the result of an array computation. tReify the element type of the result of an array computation using the array computation AST before tying the knot. -Reify the result type of a scalar expression. aReify the result types of of a scalar expression using the expression AST before tying the knot. Size of a tuple type, in bytes ~  ~   ~  [2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonell [2014..2014] Frederik M. MadsenBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None!"$%&:DMOQRTFRun a complete embedded array program using the reference interpreter.9Prepare and run an embedded array program of one argumentk    rrj     [2008..2017] Manuel M T Chakravarty, Gabriele Keller [2009..2017] Trevor L. McDonell [2013..2017] Robert Clifton-Everest [2014..2014] Frederik M. MadsenBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%Array indexing in plain Haskell code.Rank of an array."Array shape in plain Haskell code.2Total number of elements in an array of the given c.WIJ;<>=?/0123456789:@GHABCDEFKLMN   !"#$%&'OPQRSWTUVXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~3456789:;<=OPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~[qrponsz{xymlkjihgfedc^_`abvwtuOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~STUVWJINMLKFEDCBAHG@:9876543210/?=><;5673489:;<=|}~ORQP   &' !"#$%XZY]\[[2016..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None *9:;<=DRT (+*).-, (+*).-,[2016..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None %&*9:;QR' describes how to process data of some input type into some o;utput type, via a reduction using some intermediate Monoid w. For example, both sum and length below use the + monoid:-let sum = Fold (lift . Sum) (getSum . unlift)-let length = Fold (\_ -> 1) (getSum . unlift)The key is that s can be combined using  . in order to produce multiple outputs from a single% reduction of the array. For example:$let average = (/) <$> sum <*> lengthThis computes both the sum of the array as well as its length in a single traversal, then combines both results to compute the average.Because J has some numeric instances, this can also be defined more succinctly as:let average = sum / lengthA more complex example:=let sumOfSquares = Fold (lift . Sum . (^2)) (getSum . unlift)Klet standardDeviation = sqrt ((sumOfSquares / length) - (sum / length) ^ 2)kThese will all execute with a single reduction kernel and a single map to summarise (combine) the results.Apply a  to an array. Z[\Z]^Z]_Z`aZ]bZ[cZ[dZ[eZ[fghighjghkghlghmZnoZnpZnqZnrghsZtuZtvZtwZtxghyghzZ{|Z{}Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~Z~ZZZZZZZZZZZZZZZZZZZZZZZZZZ`Z`Z`Z`Z`Z`Z`Z`ZZZ]Z]Z]Z]Z[Z[ZZ((((24444445678888888:;;<<@@@@@@@@@AAAAAA A A A A AAAAA               ! "  # " * 1 ! ) / , $ % & - ' ( ) * + , + . - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I JKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~GGGGGGGGGGGCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCFCCCCCCCCCCCCCCCCCCCCCCCCCDCC      EE!"#$%&'()'*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^__``aabcdefghijklmnopqrstuvwxyz{|}~ZtZtZt                                                                                      !"#$%=&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ZZ[Z[ZZZ=7J56Z      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{=J756|}~<:############# ## # # # ######$$$$$$$$$$$$$$$$ $!$"$#$$$%$&$'$($)$*$+$,$-$.$/$0$1$2$3$4$5$6$7$8$9$:$;$<$=$>$?$@$A$B$C$D$E$F$G$H$I$J$K$L$M$N$O$P$Q$R$S$T$U$V$W$X$Y$Z$[$\$]$^$_$`$a$b$c$d$e$f$g$h$$i$$j$k$l$m$n$o$p$q$r$s$t$u$$v$w$x$$y$z${$|$}$~$$$$$$$$.$$$$$$$$$$$$$$$$$$$E$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%ZZ & & & & &'''''''''''''''''''''' '!'"''#'$''%'&(('Z()(*(+(,(i((j(k(l(m(n(o(r(s(t(u((v(w(x((y(z({(((-(.((((((((((((((E((((((((((((((/((0(1(2(3(4(5(6(7(8(9(:(;(<(=(>(?(@(A(B(C(D(E(F(G(H(I(J(K(L(M(N(O(P(Q(R(S(T(U(V(W(X(Y(Z([(\(](^(_(`(a(b(c(d(e(f(g(h(i(j(k(l(m(n(o(p(q(r(s(t(u(v(w(x(y(z({(|(}(~(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((222222222222222222222222222222222222223334444444444444444444444444444444444444444 4 4 4 4 555555555555555555555 5!66"6#6$77%7&7'88(8)8*8+8,8-8.8/808182838485868788898:8;8<8=8>8?8@8A8B8C8D8E8F8G8H8I8J8K8L8M8N8O8P8Q8R9S9T:U:V:W:X:Y:Z:[:\:]:^:_:`:a:b:c:d:e:fghiZ`;j<k@l@@m@n@o@p@qAArAsAtAuAv wxyz{|}~GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGCCCCCCCCCCHHHHHHHHHHHHHHHHHHHHHH H H H H H HHHHHHHHHHHHHHHHHHHH H!H"H#H$H%H&H'H(H)H*H+H,H-H.H/H0H1H2H3H4H5H6H7H8H9H:H;H<I=I>I?I@IAIBICIDIEIFIGIHIIIJIKILIMINIOIPIQIRISITIUIVIWIXIYIZI[I\II]I^I_I`IaIbIcIdIeIfIgIhIiIjIkIlImInIIoIpIqIrIsItIuIvIwJxJyJzJ{J|J}K~KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKLLLLM(M'MMM=MMMMMMDNN(NN'NNNNNNNNNNNNNNNNNNNNDNNOOO(OOOOOOOOOOOOOOOOOOOOOOOOOOOODOQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q !Q "Q #Q $Q %Q &Q 'Q (Q )Q *Q +Q ,Q -Q .Q /Q 0Q 1Q 2Q 3Q 4Q 5Q 6Q 7Q 8Q 9Q :Q ;Q <Q =Q >Q ?Q @Q AQ BQ CR DR ER FR GR HR IS JS KS LSS MS NSUScS OS PS QS RS SS TS US VS WS XS YS ZS [S \S ]S ^S _S `S aS bS cS dS eS fS gS hS iS jS kS lS mS nS oS pS qS rS sS tS uS vS wS xS yS zS {S |S }S ~S S S S S S S S S SS S S S S S S S S S S S SS S S T T U U U U U U U U U U U U U U V V V V V V V V V`V V V V V V VV V V V V V V V )V V V V V W WWWW W W W W W W W W W W W W W W W W W<W WW W W W W W W W W W W W W W W W W W W5W6W W W W W W W W XXXX X X X XXXXX X XUX X X XX X X X Y Y Y Y Y Y Y Y Y  II                                           m n o p q r s t u v w x y z { | }     ~  P R T V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j l       Z[  )accelerate-1.0.0.0-LXkK7tXo8jpIloeY6vHl1yData.Array.Accelerate!Data.Array.Accelerate.Data.Monoid"Data.Array.Accelerate.Data.Complex!Data.Array.Accelerate.InterpreterData.Array.Accelerate.Data.BitsData.Array.Accelerate.Data.Fold Data.AtomicData.Array.Accelerate.TypeData.Array.Accelerate.Product*Data.Array.Accelerate.Pretty.Graphviz.Type+Data.Array.Accelerate.Pretty.Graphviz.MonadData.Array.Accelerate.LifetimeSystem.Mem.WeakfinalizeWeakData.Array.Accelerate.FullListData.Array.Accelerate.Error&Data.Array.Accelerate.Debug.Monitoring!Data.Array.Accelerate.Debug.Flags!Data.Array.Accelerate.Debug.Stats!Data.Array.Accelerate.Debug.Trace!Data.Array.Accelerate.Debug.TimedData.Array.Accelerate.Async"Data.Array.Accelerate.Array.Unique*Data.Array.Accelerate.Array.Representation!Data.Array.Accelerate.Array.Sugar enumSlices Data.Array.Accelerate.Array.Data(Data.Array.Accelerate.Array.Remote.ClassusetoSeqData.Array.Accelerate.Languageslice replicate"Data.Array.Accelerate.Array.LiftedData.Array.Accelerate.AST$Data.Array.Accelerate.Analysis.Match&Data.Array.Accelerate.Analysis.Stencil"Data.Array.Accelerate.Pretty.PrintData.Array.Accelerate.Smartmapgenerate backpermutefoldscanlstencilzipWithunzipreshape%Data.Array.Accelerate.Classes.Bounded"Data.Array.Accelerate.Classes.Enum Data.Array.Accelerate.Classes.Eq!Data.Array.Accelerate.Classes.Num(Data.Array.Accelerate.Classes.Fractional&Data.Array.Accelerate.Classes.Floating!Data.Array.Accelerate.Classes.Ord"Data.Array.Accelerate.Classes.Real&Data.Array.Accelerate.Classes.Integral*Data.Array.Accelerate.Classes.FromIntegral(Data.Array.Accelerate.Classes.ToFloatingPreludeRational realToFrac&Data.Array.Accelerate.Classes.RealFrac'Data.Array.Accelerate.Classes.RealFloatData.Array.Accelerate.ClassesData.Array.Accelerate.PreludetheFold transposeData.Array.Accelerate.Lift(Data.Array.Accelerate.Trafo.Substitution Data.Array.Accelerate.Trafo.Base$Data.Array.Accelerate.Analysis.Shape%Data.Array.Accelerate.Pretty.GraphvizData.Array.Accelerate.Debug*Data.Array.Accelerate.Array.Remote.Nursery(Data.Array.Accelerate.Array.Remote.Table&Data.Array.Accelerate.Array.Remote.LRU"Data.Array.Accelerate.Array.Remote#Data.Array.Accelerate.Trafo.SharingData.Array.Accelerate.Pretty#Data.Array.Accelerate.Trafo.Algebra#Data.Array.Accelerate.Trafo.Rewrite"Data.Array.Accelerate.Trafo.Shrink$Data.Array.Accelerate.Trafo.Simplify"Data.Array.Accelerate.Trafo.FusionData.Array.Accelerate.Trafo#Data.Array.Accelerate.Analysis.TypebaseGHC.Base$GHC.Num fromInteger-GHC.Real fromRationalnegatememptymappendmconcatMonoidghc-prim GHC.TypesBoolCharDoubleFloatIntGHC.IntInt8Int16Int32Int64WordGHC.WordWord8Word16Word32Word64FalseTrue Data.Complex:+ComplexForeign.C.TypesCCharCSCharCUCharCShortCUShortCIntCUIntCLongCULongCLLongCULLongCFloatCDouble Data.Monoid<>getSumSum getProductProduct GHC.FloatatanhacoshasinhtanhcoshsinhatanacosasintancossinlogBase**sqrtlogexppidivModquotRemmoddivremquotrecip/GHC.EnummaxBoundminBoundsignumabs*+.constGHC.Err undefinederrorBoundaryClampMirrorWrapConstantIsScalar IsBoundedIsNumIsNonNum IsFloating IsIntegralSlice SliceShape CoSliceShape FullShape sliceIndexShapeDIM9DIM8DIM7DIM6DIM5DIM4DIM3DIM2DIM1DIM0SegmentsVectorScalarArrayArraysEltAnyAll:.Z fromFunctionfromListtoListStencilExpAccconstantBoundedEq==/=&&||notNum FractionalFloatingOrd<><=>=minmaxIntegral FromIntegral fromIntegral ToFloating toFloatingRealFracproperFractiontruncateroundceilingfloordiv'mod'divMod' RealFloat floatRadix floatDigits floatRange decodeFloat encodeFloatexponent significand scaleFloatisNaN isInfiniteisDenormalizedisNegativeZeroisIEEEatan2 Stencil5x5x5 Stencil3x5x5 Stencil5x3x5 Stencil5x5x3 Stencil3x3x5 Stencil3x5x3 Stencil5x3x3 Stencil3x3x3 Stencil5x5 Stencil3x5 Stencil5x3 Stencil3x3Stencil9Stencil7Stencil5Stencil3unitfold1foldSegfold1Segscanl'scanl1scanrscanr'scanr1permutestencil2 foreignAcc foreignExp>->acondawhile indexHead indexTailtoIndex fromIndex intersectcondwhile!!!shapesize shapeSizesubtractevenoddgcdlcm^^^ordchr boolToIntbitcastignore FiniteBits finiteBitSizecountLeadingZeroscountTrailingZerosBits.&..|.xor complementshiftrotatezeroBitsbitsetBitclearBit complementBittestBitisSignedshiftL unsafeShiftLshiftR unsafeShiftRrotateLrotateRpopCount$fFiniteBitsCUShort$fFiniteBitsCShort$fFiniteBitsCULLong$fFiniteBitsCLLong$fFiniteBitsCULong$fFiniteBitsCLong$fFiniteBitsCUInt$fFiniteBitsCInt$fFiniteBitsWord64$fFiniteBitsWord32$fFiniteBitsWord16$fFiniteBitsWord8$fFiniteBitsWord$fFiniteBitsInt64$fFiniteBitsInt32$fFiniteBitsInt16$fFiniteBitsInt8$fFiniteBitsInt$fFiniteBitsBool $fBitsCUShort $fBitsCShort $fBitsCULLong $fBitsCLLong $fBitsCULong $fBitsCLong $fBitsCUInt $fBitsCInt $fBitsWord64 $fBitsWord32 $fBitsWord16 $fBitsWord8 $fBitsWord $fBitsInt64 $fBitsInt32 $fBitsInt16 $fBitsInt8 $fBitsInt $fBitsBoolUnliftunliftLiftPlainliftlift1lift2lift3ilift1ilift2ilift3 magnitudephasepolarmkPolarcisrealimag conjugate$fFromIntegralaComplex $fFloatingExp$fFractionalExp$fNumExp $fEqComplex$fUnliftExpComplex$fLiftExpComplex$fIsProductcstComplex $fEltComplex IfThenElseEltT ifThenElseindexedimapzipWith3zipWith4zipWith5zipWith6zipWith7zipWith8zipWith9izipWith izipWith3 izipWith4 izipWith5 izipWith6 izipWith7 izipWith8 izipWith9zipzip3zip4zip5zip6zip7zip8zip9unzip3unzip4unzip5unzip6unzip7unzip8unzip9foldAllfold1Allallanyandorsumproductminimummaximumprescanl postscanlprescanr postscanrscanlSeg scanl'Seg scanl1Seg prescanlSeg postscanlSegscanrSeg scanr'Seg scanr1Seg prescanrSeg postscanrSegflattenfill enumFromN enumFromStepN++filtergatherscatterreversetakedropinittailslitcompute?|?caseofiteratesfoldlfstafstsndasndcurryuncurryindex0index1unindex1index2unindex2index3unindex3nulllengthrunrun1 evalPrimConstevalPrimevalPrj indexArray arrayRank arrayShape arraySize $fMonoidExp $fMonoidExp0 $fMonoidExp1 $fMonoidExp2 $fMonoidExp3 $fOrdProduct $fEqProduct $fMonoidExp4$fUnliftExpProduct$fLiftExpProduct$fIsProductEltProduct $fEltProduct$fOrdSum$fEqSum $fNumExp0 $fMonoidExp5$fUnliftExpSum $fLiftExpSum$fIsProductEltSum$fEltSumrunFold$fFloatingFold$fFractionalFold $fNumFold$fApplicativeFold $fFunctorFoldAtomicnewaddatomic_fetch_and_and_64atomic_fetch_and_add_64 BitSizeEq ScalarType BoundedTypeNumType NonNumType FloatingType IntegralTypeBitSize TupleType UnitTuple SingleTuple PairTuple scalarType boundedTypenumType nonNumType floatingType integralType NumScalarTypeNonNumScalarTypeIntegralBoundedTypeNonNumBoundedTypeIntegralNumTypeFloatingNumTypeTypeBoolTypeChar TypeCChar TypeCSChar TypeCUChar TypeFloat TypeDouble TypeCFloat TypeCDoubleTypeIntTypeInt8 TypeInt16 TypeInt32 TypeInt64TypeWord TypeWord8 TypeWord16 TypeWord32 TypeWord64 TypeCShort TypeCUShortTypeCInt TypeCUInt TypeCLong TypeCULong TypeCLLong TypeCULLong NonNumDict FloatingDict IntegralDict integralDict floatingDict nonNumDict$fIsScalarCUChar$fIsScalarCSChar$fIsScalarCChar$fIsScalarChar$fIsScalarBool$fIsScalarCDouble$fIsScalarCFloat$fIsScalarDouble$fIsScalarFloat$fIsScalarCULLong$fIsScalarCLLong$fIsScalarCULong$fIsScalarCLong$fIsScalarCUInt$fIsScalarCInt$fIsScalarCUShort$fIsScalarCShort$fIsScalarWord64$fIsScalarWord32$fIsScalarWord16$fIsScalarWord8$fIsScalarWord$fIsScalarInt64$fIsScalarInt32$fIsScalarInt16$fIsScalarInt8 $fIsScalarInt$fIsBoundedCUChar$fIsBoundedCSChar$fIsBoundedCChar$fIsBoundedChar$fIsBoundedBool$fIsBoundedCULLong$fIsBoundedCLLong$fIsBoundedCULong$fIsBoundedCLong$fIsBoundedCUInt$fIsBoundedCInt$fIsBoundedCUShort$fIsBoundedCShort$fIsBoundedWord64$fIsBoundedWord32$fIsBoundedWord16$fIsBoundedWord8$fIsBoundedWord$fIsBoundedInt64$fIsBoundedInt32$fIsBoundedInt16$fIsBoundedInt8$fIsBoundedInt$fIsNumCDouble $fIsNumCFloat $fIsNumDouble $fIsNumFloat$fIsNumCULLong $fIsNumCLLong $fIsNumCULong $fIsNumCLong $fIsNumCUInt $fIsNumCInt$fIsNumCUShort $fIsNumCShort $fIsNumWord64 $fIsNumWord32 $fIsNumWord16 $fIsNumWord8 $fIsNumWord $fIsNumInt64 $fIsNumInt32 $fIsNumInt16 $fIsNumInt8 $fIsNumInt$fIsNonNumCUChar$fIsNonNumCSChar$fIsNonNumCChar$fIsNonNumChar$fIsNonNumBool$fIsFloatingCDouble$fIsFloatingCFloat$fIsFloatingDouble$fIsFloatingFloat$fIsIntegralCULLong$fIsIntegralCLLong$fIsIntegralCULong$fIsIntegralCLong$fIsIntegralCUInt$fIsIntegralCInt$fIsIntegralCUShort$fIsIntegralCShort$fIsIntegralWord64$fIsIntegralWord32$fIsIntegralWord16$fIsIntegralWord8$fIsIntegralWord$fIsIntegralInt64$fIsIntegralInt32$fIsIntegralInt16$fIsIntegralInt8$fIsIntegralInt$fShowTupleType$fShowScalarType$fShowBoundedType $fShowNumType$fShowNonNumType$fShowFloatingType$fShowIntegralType byteSwap64 byteSwap32 byteSwap16 IsProductProdRTupleIdxProdReprfromProdtoProdprod ProdRunit ProdRsnoc ZeroTupIdx SuccTupIdx$fIsProductcst(,,,,,,,,,,,,,,)$fIsProductcst(,,,,,,,,,,,,,)$fIsProductcst(,,,,,,,,,,,,)$fIsProductcst(,,,,,,,,,,,)$fIsProductcst(,,,,,,,,,,)$fIsProductcst(,,,,,,,,,)$fIsProductcst(,,,,,,,,)$fIsProductcst(,,,,,,,)$fIsProductcst(,,,,,,)$fIsProductcst(,,,,,)$fIsProductcst(,,,,)$fIsProductcst(,,,)$fIsProductcst(,,)$fIsProductcst(,)$fIsProductcst()EdgeVertexPortLabelNodeIdNode StatementNEGGraphTreeLeafForestppGraph ppSubgraph ppStatementppEdgeppVertexppNode ppNodeTreeppNodeId $fShowGraph$fHashableNodeId $fFunctorTreeDotStatefreshdotGraphdotEdgesdotNodesDot emptyStaterunDotevalDotexecDotmkLabelmkNodeIdmkGraph mkSubgraphLTFLifetime newLifetime withLifetime touchLifetime addFinalizermkWeakunsafeGetValue mkWeakPtr finalizer touchIORef $fEqLifetimeListNilConsFullListFLcons singletonsizeLlookuplookupL lookupDelete lookupDeleteLmapM_mapML_$fEqList $fEqFullList internalError internalCheck indexCheckinternalWarningCheckBoundsUnsafeInternal boundsError unsafeError boundsCheck unsafeCheck boundsWarning unsafeWarningcallerrorQcheckQwarningQ withLocationlocatedMessage formatLocmessagedoChecksdoBoundsChecksdoUnsafeChecksdoInternalChecksbeginMonitoringinitAccMetrics withProcessoraddProcessorTime ProcessorNativePTXCUDAdidAllocateBytes didEvictLRU didMajorGCaccInitwhenunlessFlagsFlagSpecOptionMode DebugFlagdef acc_sharing exp_sharingfusionsimplify flush_cache fast_mathverbose dump_phases dump_sharingdump_simpl_statsdump_simpl_iterationsdump_vectorisationdump_dotdump_simpl_dotdump_gc dump_gc_statsdebug_ccdump_ccdump_lddump_asm dump_exec dump_schedallFlagsfflagsdflags getUpdateArgs queryFlagsetFlag clearFlagsetFlags clearFlags$fDebugFlagMaybe$fDebugFlagBoolTickInline RuleFired KnownBranch BetaReduce SubstitutionSimplifierDone FusionDoneId TickCount SimplStatsSimpleDetailticksdetailsinline ruleFired knownBranch betaReduce substitutionsimplifierDone fusionDonetickannotate statisticsinitSimplCountresetSimplCount simplTick pprSimplCount simplCountaddTick pprTickCount pprTickGroup tickToTag tickToStr pprTickCtxpprId$fShowSimplStatsshowFFloatSIBaseNothingJusttracetraceIO traceEvent putTraceMsg traceEventIOtimedelapsedasyncasyncOn GHC.Conc.SyncforkOn asyncBoundControl.ConcurrentforkOSwaitpollcancelAsync asyncUsing rawForkIO rawForkOn UniqueArraynewUniqueArraywithUniqueArrayPtrunsafeUniqueArrayPtrGHC.ForeignPtrunsafeForeignPtrToPtrtouchUniqueArray uniqueArrayIduniqueArrayData$fNFDataUniqueArray SliceIndex sliceShapeSliceNilSliceAll SliceFixedrankemptyunionbounditeriter1 rangeToShape shapeToRange shapeToList listToShape$fShowSliceIndex $fSlice(,) $fSlice(,)0 $fSlice() $fShape(,) $fShape() ArrayEltRArrayEltMutableArrayData ArrayData runArrayDataregisterForeignPtrAllocator!mallocPlainForeignPtrBytesAlignedmallocForeignPtr HTYPE_INT HTYPE_WORD HTYPE_LONGHTYPE_UNSIGNED_LONG HTYPE_CCHAR ArrayPtrsarrayEltunsafeIndexArrayDataptrsOfArrayDatatouchArrayData newArrayDataunsafeReadArrayDataunsafeWriteArrayDataunsafeFreezeArrayDataptrsOfMutableArrayData ArrayEltRunit ArrayEltRint ArrayEltRint8ArrayEltRint16ArrayEltRint32ArrayEltRint64 ArrayEltRwordArrayEltRword8ArrayEltRword16ArrayEltRword32ArrayEltRword64ArrayEltRcshortArrayEltRcushort ArrayEltRcintArrayEltRcuintArrayEltRclongArrayEltRculongArrayEltRcllongArrayEltRcullongArrayEltRfloatArrayEltRdoubleArrayEltRcfloatArrayEltRcdouble ArrayEltRbool ArrayEltRcharArrayEltRccharArrayEltRcscharArrayEltRcuchar ArrayEltRpair GArrayDataAD_Pair AD_CUChar AD_CSCharAD_CCharAD_CharAD_Bool AD_CDouble AD_CFloat AD_DoubleAD_Float AD_CULLong AD_CLLong AD_CULongAD_CLongAD_CUIntAD_CInt AD_CUShort AD_CShort AD_Word64 AD_Word32 AD_Word16AD_Word8AD_WordAD_Int64AD_Int32AD_Int16AD_Int8AD_IntAD_Unit fstArrayData sndArrayData pairArrayDatatoBoolfromBoolunsafeIndexArrayunsafeReadArrayunsafeWriteArray newArrayData'__mallocForeignPtrBytes $fArrayElt(,)$fArrayEltCUChar$fArrayEltCSChar$fArrayEltCChar$fArrayEltChar$fArrayEltBool$fArrayEltCDouble$fArrayEltCFloat$fArrayEltDouble$fArrayEltFloat$fArrayEltCULLong$fArrayEltCLLong$fArrayEltCULong$fArrayEltCLong$fArrayEltCUInt$fArrayEltCInt$fArrayEltCUShort$fArrayEltCShort$fArrayEltWord64$fArrayEltWord32$fArrayEltWord16$fArrayEltWord8$fArrayEltWord$fArrayEltInt64$fArrayEltInt32$fArrayEltInt16$fArrayEltInt8 $fArrayEltInt $fArrayElt()D:R:GArrayDataba(,)0D:R:GArrayDatabaCUChar0D:R:GArrayDatabaCSChar0D:R:GArrayDatabaCChar0D:R:GArrayDatabaChar0D:R:GArrayDatabaBool0D:R:GArrayDatabaCDouble0D:R:GArrayDatabaCFloat0D:R:GArrayDatabaDouble0D:R:GArrayDatabaFloat0D:R:GArrayDatabaCULLong0D:R:GArrayDatabaCLLong0D:R:GArrayDatabaCULong0D:R:GArrayDatabaCLong0D:R:GArrayDatabaCUInt0D:R:GArrayDatabaCInt0D:R:GArrayDatabaCUShort0D:R:GArrayDatabaCShort0D:R:GArrayDatabaWord640D:R:GArrayDatabaWord320D:R:GArrayDatabaWord160D:R:GArrayDatabaWord80D:R:GArrayDatabaWord0D:R:GArrayDatabaInt640D:R:GArrayDatabaInt320D:R:GArrayDatabaInt160D:R:GArrayDatabaInt80D:R:GArrayDatabaInt0D:R:GArrayDataba()0 RemoteMemory RemotePtr mallocRemote pokeRemote peekRemote castRemotePtrtotalRemoteMemavailableRemoteMemremoteAllocationSizePrimEltDivision sliceAnyIndexsliceNoneIndexTupleRAtupleTuple TupleReprEltReprDivideSplitsingletonScalarType concatVectors allocateArray showShape DivisionSlice slicesIndexNilAtupSnocAtupNilTupSnocTuparraysflavourtoArrfromArr ArraysFlavour ArraysFunit ArraysFarray ArraysFtupleArraysR ArraysRunit ArraysRarray ArraysRpairIsAtupleArrReprForeign strForeigneltTypefromElttoEltIsTuple fromTupletoTuple liftToElt liftToElt2 sinkFromElt sinkFromElt2 fromAtupletoAtupletuple$fDivisionDivide $fDivisionAny $fDivision:. $fDivision:.0 $fDivisionZ $fSliceAny $fSlice:. $fSlice:.0$fSliceZ $fShape:.$fShapeZ $fNFDataArray $fIsListArray $fShowArray $fShowArray0 $fShowArray1 $fShowArray2 $fEqArray$fArrays(,,,,,,,,,,,,,,)$fArrays(,,,,,,,,,,,,,)$fArrays(,,,,,,,,,,,,)$fArrays(,,,,,,,,,,,)$fArrays(,,,,,,,,,,)$fArrays(,,,,,,,,,)$fArrays(,,,,,,,,)$fArrays(,,,,,,,)$fArrays(,,,,,,)$fArrays(,,,,,)$fArrays(,,,,) $fArrays(,,,) $fArrays(,,) $fArrays(,) $fArraysArray $fArrays()$fElt(,,,,,,,,,,,,,,)$fElt(,,,,,,,,,,,,,)$fElt(,,,,,,,,,,,,)$fElt(,,,,,,,,,,,)$fElt(,,,,,,,,,,)$fElt(,,,,,,,,,)$fElt(,,,,,,,,)$fElt(,,,,,,,) $fElt(,,,,,,) $fElt(,,,,,) $fElt(,,,,) $fElt(,,,) $fElt(,,)$fElt(,) $fEltCUChar $fEltCSChar $fEltCChar $fEltChar $fEltBool $fEltCDouble $fEltCFloat $fEltDouble $fEltFloat $fEltCULLong $fEltCLLong $fEltCULong $fEltCLong $fEltCUInt $fEltCInt $fEltCUShort $fEltCShort $fEltWord64 $fEltWord32 $fEltWord16 $fEltWord8 $fEltWord $fEltInt64 $fEltInt32 $fEltInt16 $fEltInt8$fEltInt$fEltAny $fEltAny0$fEltAll$fElt:.$fEltZ$fElt()$fShow:. IsArraysFlatIsTypeableArrRepr IsConstrainedIsC LiftedArrayLiftedTupleRepr LiftedReprVector'isTypeableArrRepr isArraysFlatscalaremptyVec elements'shapes'empty'length'drop'vec2Vec'toList' fromList'$fArraysVector'$fIsProductArraysVector'PrimFun PrimConst PreOpenExpPreExpOpenExpFunPreFunOpenFun PreOpenFunStencilR PreOpenAccAfunPreAfun PreOpenAfun NFDataAccPrimAddPrimSubPrimMulPrimNegPrimAbsPrimSigPrimQuotPrimRem PrimQuotRemPrimIDivPrimMod PrimDivModPrimBAndPrimBOrPrimBXorPrimBNot PrimBShiftL PrimBShiftR PrimBRotateL PrimBRotateR PrimPopCountPrimCountLeadingZerosPrimCountTrailingZerosPrimFDiv PrimRecipPrimSinPrimCosPrimTanPrimAsinPrimAcosPrimAtanPrimSinhPrimCoshPrimTanh PrimAsinh PrimAcosh PrimAtanhPrimExpFloatingPrimSqrtPrimLogPrimFPow PrimLogBase PrimTruncate PrimRound PrimFloor PrimCeiling PrimIsNaN PrimAtan2PrimLtPrimGtPrimLtEqPrimGtEqPrimEqPrimNEqPrimMaxPrimMinPrimLAndPrimLOrPrimLNotPrimOrdPrimChr PrimBoolToIntPrimFromIntegralPrimToFloating PrimCoerce PrimMinBound PrimMaxBoundPrimPiLetVarConstPrjIndexNil IndexCons IndexHead IndexTailIndexAny IndexSlice IndexFullToIndex FromIndexCondWhilePrimAppIndex LinearIndex ShapeSize IntersectUnionBodyLam StencilRunit3 StencilRunit5 StencilRunit7 StencilRunit9 StencilRtup3 StencilRtup5 StencilRtup7 StencilRtup9 stencilAccessAletAvarAprjApplyAforeignAcondAwhileUseUnitReshapeGenerate Transform ReplicateMapZipWithFold1FoldSegFold1SegScanlScanl'Scanl1ScanrScanr'Scanr1Permute BackpermuteStencil2OpenAccOpenAfunAbodyAlamValEltEmptyEltPushEltValEmptyPushIdxZeroIdxSuccIdxidxToInt tupleIdxToIntprjprjElt invertShapernfIdx rnfTupleIdx rnfOpenAfun rnfOpenAccrnfPreOpenAfun rnfPreOpenAcc rnfAtuple rnfArrays rnfBoundary rnfPreOpenFun rnfPreOpenExprnfTuplernfConst rnfPrimConst rnfPrimFun rnfSliceIndex rnfScalarTypernfBoundedType rnfNumType rnfNonNumTypernfIntegralTypernfFloatingType showPreAccOp showArraysshowShortendArr showPreExpOp$fNFDataPreOpenFun$fNFDataPreOpenExp$fNFDataOpenAcc$fNFDataPreOpenAfun$fStencil:.a(,,,,,,,,)$fStencil:.a(,,,,,,)$fStencil:.a(,,,,)$fStencil:.a(,,)$fStencil:.e(,,,,,,,,)$fStencil:.e(,,,,,,)$fStencil:.e(,,,,)$fStencil:.e(,,)HashAccMatchAcc matchOpenAccmatchPreOpenAcc matchAtuple matchOpenAfunmatchPreOpenAfun matchBoundary matchArrays matchOpenExpmatchPreOpenExp matchOpenFunmatchPreOpenFun matchConstevalEqmatchIdx matchTupleIdx matchTuplematchSliceRestrictmatchSliceExtendmatchPrimConst matchPrimFun matchPrimFun'matchTupleTypematchScalarType matchNumTypematchBoundedTypematchIntegralTypematchFloatingTypematchNonNumTypecommuteshashIdx hashTupleIdx hashOpenAcchashPreOpenAcc hashArrays hashAtuplehashAfun hashBoundary hashOpenExphashPreOpenExphashPreOpenFun hashTuple hashPrimConst hashPrimFunData.Type.Equality:~:Refloffsets positionsRoffsets2 innermost PrettyEnv prettyEnv PrettyAcc prettyOpenAccprettyOpenAfun prettyOpenFun prettyOpenExpprettyPreOpenAccprettyPreOpenAfun prettyPreFunprettyPreOpenFun prettyPreExpprettyPreOpenExp prettyAtuple prettyTupleprettyTupleIdx prettyConst prettyPrim prettyArrays prettyArraynoParens encloseSepsizeEnv$fPrettyEnv(,) $fPrettyEnv()PreAccGHC.ShowShow StencilRepr stencilPrjTagAtagPipeLevelatup2atup3atup4atup5atup6atup7atup8atup9atup10atup11atup12atup13atup14atup15unatup2unatup3unatup4unatup5unatup6unatup7unatup8unatup9unatup10unatup11unatup12unatup13unatup14unatup15tix0tix1tix2tix3tix4tix5tix6tix7tix8tup2tup3tup4tup5tup6tup7tup8tup9tup10tup11tup12tup13tup14tup15untup2untup3untup4untup5untup6untup7untup8untup9untup10untup11untup12untup13untup14untup15 mkMinBound mkMaxBoundmkPimkSinmkCosmkTanmkAsinmkAcosmkAtanmkSinhmkCoshmkTanhmkAsinhmkAcoshmkAtanh mkExpFloatingmkSqrtmkLogmkFPow mkLogBasemkAddmkSubmkMulmkNegmkAbsmkSigmkQuotmkRem mkQuotRemmkIDivmkModmkDivModmkBAndmkBOrmkBXormkBNot mkBShiftL mkBShiftR mkBRotateL mkBRotateR mkPopCountmkCountLeadingZerosmkCountTrailingZerosmkFDivmkRecip mkTruncatemkRoundmkFloor mkCeilingmkAtan2mkIsNaNmkLtmkGtmkLtEqmkGtEqmkEqmkNEqmkMaxmkMinmkLAndmkLOrmkLNotmkOrdmkChrmkFromIntegral mkToFloating mkBoolToInt mkBitcastmkUnsafeCoerce$$$$$$$$$$$$$$ $fBoundedExp $fBoundedExp0 $fBoundedExp1 $fBoundedExp2 $fBoundedExp3 $fBoundedExp4 $fBoundedExp5 $fBoundedExp6 $fBoundedExp7 $fBoundedExp8 $fBoundedExp9$fBoundedExp10$fBoundedExp11$fBoundedExp12$fBoundedExp13$fBoundedExp14$fBoundedExp15$fBoundedExp16$fBoundedExp17$fBoundedExp18$fBoundedExp19$fBoundedExp20$fBoundedExp21$fBoundedExp22$fBoundedExp23$fBoundedExp24$fBoundedExp25$fBoundedExp26$fBoundedExp27$fBoundedExp28$fBoundedExp29$fBoundedExp30$fBoundedExp31$fBoundedExp32$fBoundedExp33$fBoundedExp34$fBoundedExp35$fBoundedExp36Enum preludeError $fEnumExp$fEqExp$fEq(,,,,,,,,,,,,,,)$fEq(,,,,,,,,,,,,,)$fEq(,,,,,,,,,,,,)$fEq(,,,,,,,,,,,)$fEq(,,,,,,,,,,)$fEq(,,,,,,,,,)$fEq(,,,,,,,,) $fEq(,,,,,,,) $fEq(,,,,,,) $fEq(,,,,,) $fEq(,,,,) $fEq(,,,)$fEq(,,)$fEq(,) $fEqCDouble $fEqCFloat $fEqDouble $fEqFloat $fEqCSChar $fEqCUChar $fEqCChar$fEqChar$fEqBool $fEqCUShort $fEqCShort $fEqCULLong $fEqCLLong $fEqCULong $fEqCLong $fEqCUInt$fEqCInt $fEqWord64 $fEqWord32 $fEqWord16 $fEqWord8$fEqWord $fEqInt64 $fEqInt32 $fEqInt16$fEqInt8$fEqInt$fEq() $fNumExp1 $fNumExp2 $fNumExp3 $fNumExp4 $fNumExp5 $fNumExp6 $fNumExp7 $fNumExp8 $fNumExp9 $fNumExp10 $fNumExp11 $fNumExp12 $fNumExp13 $fNumExp14 $fNumExp15 $fNumExp16 $fNumExp17 $fNumExp18 $fNumExp19 $fNumExp20$fFractionalExp0$fFractionalExp1$fFractionalExp2$fFloatingExp0$fFloatingExp1$fFloatingExp2$fOrdExp$fOrd(,,,,,,,,,,,,,,)$fOrd(,,,,,,,,,,,,,)$fOrd(,,,,,,,,,,,,)$fOrd(,,,,,,,,,,,)$fOrd(,,,,,,,,,,)$fOrd(,,,,,,,,,)$fOrd(,,,,,,,,)$fOrd(,,,,,,,) $fOrd(,,,,,,) $fOrd(,,,,,) $fOrd(,,,,) $fOrd(,,,) $fOrd(,,)$fOrd(,) $fOrdCDouble $fOrdCFloat $fOrdDouble $fOrdFloat $fOrdCSChar $fOrdCUChar $fOrdCChar $fOrdChar $fOrdBool $fOrdCUShort $fOrdCShort $fOrdCULLong $fOrdCLLong $fOrdCULong $fOrdCLong $fOrdCUInt $fOrdCInt $fOrdWord64 $fOrdWord32 $fOrdWord16 $fOrdWord8 $fOrdWord $fOrdInt64 $fOrdInt32 $fOrdInt16 $fOrdInt8$fOrdInt$fOrd()Real $fRealExp $fIntegralExp$fIntegralExp0$fIntegralExp1$fIntegralExp2$fIntegralExp3$fIntegralExp4$fIntegralExp5$fIntegralExp6$fIntegralExp7$fIntegralExp8$fIntegralExp9$fIntegralExp10$fIntegralExp11$fIntegralExp12$fIntegralExp13$fIntegralExp14$fIntegralExp15$fIntegralExp16 integer-gmpGHC.Integer.TypeInteger$fFromIntegralCULLongCDouble$fToFloatingCDoubleCDoubledefaultProperFraction $fRealFracExp$fRealFracCDouble$fRealFracCFloat$fRealFracDouble$fRealFracFloat$fRealFloatExp$fRealFloatCDouble$fRealFloatCFloat$fRealFloatDouble$fRealFloatFloat bitDefaulttestBitDefault shiftDefault shiftLDefault shiftRDefaultshiftRADefaultshiftRLDefault rotateDefaultrotateDefault'rotateLDefaultrotateRDefaultisSignedDefault_popCountDefaultpopCountKernighanpopCnt8popCnt16popCnt32popCnt64$fUnliftAcc(,,,,,,,,,,,,,,)$fLiftAcc(,,,,,,,,,,,,,,)$fUnliftAcc(,,,,,,,,,,,,,)$fLiftAcc(,,,,,,,,,,,,,)$fUnliftAcc(,,,,,,,,,,,,)$fLiftAcc(,,,,,,,,,,,,)$fUnliftAcc(,,,,,,,,,,,)$fLiftAcc(,,,,,,,,,,,)$fUnliftAcc(,,,,,,,,,,)$fLiftAcc(,,,,,,,,,,)$fUnliftAcc(,,,,,,,,,)$fLiftAcc(,,,,,,,,,)$fUnliftAcc(,,,,,,,,)$fLiftAcc(,,,,,,,,)$fUnliftAcc(,,,,,,,)$fLiftAcc(,,,,,,,)$fUnliftAcc(,,,,,,)$fLiftAcc(,,,,,,)$fUnliftAcc(,,,,,)$fLiftAcc(,,,,,)$fUnliftAcc(,,,,)$fLiftAcc(,,,,)$fUnliftAcc(,,,)$fLiftAcc(,,,)$fUnliftAcc(,,) $fLiftAcc(,,)$fUnliftAcc(,) $fLiftAcc(,)$fLiftAccArray$fUnliftExp(,,,,,,,,,,,,,,)$fLiftExp(,,,,,,,,,,,,,,)$fUnliftExp(,,,,,,,,,,,,,)$fLiftExp(,,,,,,,,,,,,,)$fUnliftExp(,,,,,,,,,,,,)$fLiftExp(,,,,,,,,,,,,)$fUnliftExp(,,,,,,,,,,,)$fLiftExp(,,,,,,,,,,,)$fUnliftExp(,,,,,,,,,,)$fLiftExp(,,,,,,,,,,)$fUnliftExp(,,,,,,,,,)$fLiftExp(,,,,,,,,,)$fUnliftExp(,,,,,,,,)$fLiftExp(,,,,,,,,)$fUnliftExp(,,,,,,,)$fLiftExp(,,,,,,,)$fUnliftExp(,,,,,,)$fLiftExp(,,,,,,)$fUnliftExp(,,,,,)$fLiftExp(,,,,,)$fUnliftExp(,,,,)$fLiftExp(,,,,)$fUnliftExp(,,,)$fLiftExp(,,,)$fUnliftExp(,,) $fLiftExp(,,)$fUnliftExp(,) $fLiftExp(,)$fLiftExpCUChar$fLiftExpCSChar$fLiftExpCChar $fLiftExpChar $fLiftExpBool$fLiftExpCDouble$fLiftExpCFloat$fLiftExpDouble$fLiftExpFloat$fLiftExpCULLong$fLiftExpCLLong$fLiftExpCULong$fLiftExpCLong$fLiftExpCUInt $fLiftExpCInt$fLiftExpCUShort$fLiftExpCShort$fLiftExpWord64$fLiftExpWord32$fLiftExpWord16$fLiftExpWord8 $fLiftExpWord$fLiftExpInt64$fLiftExpInt32$fLiftExpInt16 $fLiftExpInt8 $fLiftExpInt $fLiftExpAny $fUnliftExp:.$fUnliftExp:.0 $fLiftExp:. $fLiftExp:.0 $fLiftExp:.1 $fUnliftExpZ $fLiftExpZ $fUnliftExp() $fLiftExp()$fUnliftAccAcc $fLiftAccAcc$fUnliftExpExp $fLiftExpExp mkHeadFlags mkTailFlags segmentedindex1'gatherIf scatterIf emptyArraymatchShapeType$fIfThenElseAcc$fIfThenElseExp substitutecomposeIdxAIAunIA SyntacticAccavarInaccOut weakenAcc RebuildAccIdxEIEunIE SyntacticExpvarInexpOut weakenExp weakenExpAcc:?>SinkExpweakenESinkweaken:> RebuildTupunRTupRebuildableAccRebuildableExprebuildPartialErebuildE RebuildableAccClorebuildPartialrebuildAIdentity runIdentitysubTopsubAtop strengthen strengthenEshiftErebuildPreOpenExp rebuildTup rebuildFunshiftArebuildOpenAccrebuildPreOpenAcc rebuildAfun rebuildAtup$fSyntacticAccPreOpenAcc$fSyntacticAccIdxA$fSyntacticExpPreOpenExp$fSyntacticExpIdxE$fSinkExpPreOpenFun$fSinkExpPreOpenExp $fSinkOpenAcc$fSinkRebuildTup$fSinkPreOpenFun$fSinkPreOpenExp$fSinkPreOpenAfun$fSinkPreOpenAcc $fSinkIdx$fRebuildableExpPreOpenFun$fRebuildableExpPreOpenExp$fRebuildableOpenAcc$fRebuildableRebuildTup$fRebuildablePreOpenAfun$fRebuildablePreOpenAcc$fRebuildablePreOpenFun$fRebuildablePreOpenExp$fApplicativeIdentity$fFunctorIdentityinlineA SupplementBaseSupPushSupExtendBaseEnvPushEnvGammaEmptyExpPushExpDelayedOpenAccManifestDelayedextentDindexD linearIndexDDelayedOpenFunDelayedOpenExpDelayedOpenAfun DelayedFun DelayedExp DelayedAfun DelayedAccMatchmatchKitinjectextract fromOpenAccmatchAcchashAcc prettyAcckmap fromOpenAfun hashDelayed matchDelayedrnfDelayedOpenAcc prettyDelayedincExpprjExp weakenGamma1 sinkGamma lookupExpappendbindsinksink1bindExpssubApply$fNFDataDelayedOpenAcc$fKitDelayedOpenAcc$fSinkDelayedOpenAcc$fRebuildableDelayedOpenAcc $fMatchacc$fMatchPreOpenAcc$fMatchPreOpenFun$fMatchPreOpenExp $fMatchIdx $fKitOpenAccaccDim preAccDimexpDimAccDim delayedDimndimgraphDelayedAccgraphDelayedAfunFVAccPNodePDocFull PrettyGraphAvalAemptyApushcfgIncludeShape cfgUnique avalToValaprjmkNodemkTFsimplegraphDelayedOpenAccprettyDelayedOpenAccprettyDelayedAfunprettyDelayedAtuplereplantprettyDelayedFunprettyDelayedExpprettyDelayedOpenFunprettyDelayedOpenExp fvPreOpenFun fvPreOpenExp$fPrettyGraphPreOpenAfun$fPrettyGraphDelayedOpenAccdumpSimplStats dumpGraphdebuggingIsEnabledmonitoringIsEnabledinsertcleanupNRSNursery StableArrayfreemalloc freeStableinsertUnmanagedcleanpurgereclaimmakeStableArraymakeWeakArrayData RemoteArray MemoryTableMT HashTableremoteFinalizer showBytes management$fShowStableArrayTask completed withRemoteUsed TimestampStatusCleanDirty UnmanagedEvictedUseTableUTmallocWithUsageevictLRUdeletecache_finalizer cleanUsesincCount isEvicted withMVar'$fTask()recoverAccSharingrecoverExpSharingrecoverSeqSharing floatOutAcc convertAcc convertAfunconvertOpenAccconvertSharingAccconvertBoundary convertFun convertExpconvertSharingExpconvertSharingTupleconvertSharingFun1convertSharingFun2convertSharingStencilFun1convertSharingStencilFun2recoverSharingAccStableSharingAcc NodeCount AccNodeCount ExpNodeCountNodeName NodeCountsStableSharingExpRootExp ScopedExp UnscopedExp SharingExp VarSharing LetSharing ExpSharing StableExpName ScopedAcc UnscopedAcc SharingAcc AvarSharing AletSharing AccSharing StableAccNameOccMap OccMapHash ASTHashTableStableNameHeight StableASTNameFunction FunctionRconvert Afunction AfunctionRaconvertLayout EmptyLayout PushLayoutConfigprjIdxpossiblyNestedErr incLayout sizeLayoutconvertSharingAfun1convertSharingAtuplemkIndex mkReplicateconvertOpenExp makeStableAST higherSNHhashStableNameHeightnewASTHashTableenterOcc freezeOccMaplookupWithASTNamelookupWithSharingAcclookupWithSharingExp higherSSAmatchStableAccnoStableAccName higherSSEmatchStableExpnoStableExpName makeOccMapAccmakeOccMapSharingAccmakeOccMapAfun1 makeOccMapExpmakeOccMapFun1makeOccMapFun2makeOccMapStencil1makeOccMapStencil2makeOccMapRootExpmakeOccMapSharingExp noNodeCounts insertAccNode insertExpNode cleanCountsnodeName+++buildInitialEnvAccbuildInitialEnvExp isFreeVardetermineScopesAccdetermineScopesSharingAccdetermineScopesExpdetermineScopesSharingExprecoverSharingExp traceLine traceChunk tracePure$fShowNodeName$fHashableNodeName $fEqNodeName$fEqStableSharingExp$fShowStableSharingExp$fEqStableSharingAcc$fShowStableSharingAcc$fEqStableNameHeight$fHashableStableASTName$fEqStableASTName$fShowStableASTName $fFunctionExp$fFunction(->)$fAfunctionAcc$fAfunction(->)wide$fShowPreOpenExp$fShowPreOpenFun$fShowPreOpenAfun$fShowDelayedOpenAcc $fShowOpenAcc:-> propagate evalPrimAppeval1eval2pprFunevalAddevalAdd'evalSubevalSub'evalMulevalMul'evalNegevalAbsevalSigevalQuotevalRem evalQuotRemevalIDivevalMod evalDivModevalBAndevalBOrevalBXorevalBNot evalBShiftL evalBShiftR evalBRotateL evalBRotateR evalPopCountevalCountLeadingZerosevalCountTrailingZerosevalFDiv evalFDiv' evalRecipevalSinevalCosevalTanevalAsinevalAcosevalAtanevalSinhevalCoshevalTanh evalAsinh evalAcosh evalAtanhevalExpFloatingevalSqrtevalLogevalFPow evalLogBase evalAtan2 evalTruncate evalRound evalFloor evalCeiling evalIsNaNevalLtevalGtevalLtEqevalGtEqevalNEqevalMaxevalMinevalLAndevalLOrevalLNotevalOrdevalChr evalBoolToIntevalFromIntegralevalToFloating evalCoerce evalMinBound evalMaxBoundevalPiconvertSegmentsconvertSegmentsAfun UsesOfAcc ReduceAcc ShrinkAccShrinkshrinkshrink' shrinkExp shrinkFun shrinkPreAccbasicReduceAcc usesOfExp usesOfPreAcc$fShrinkPreOpenFun$fShrinkPreOpenExpStats_terms_types_binders_vars_opsSimplifylocalCSE globalCSEsimplifyOpenExpsimplifyOpenFun simplifyExp simplifyFuntermstypesbindersvarsops&+~summariseOpenFunsummariseOpenExp $fShowStats$fSimplifyPreOpenExp$fSimplifyPreOpenFunEmbedAcc CunctationDoneYieldStepEmbedElimAccwithSimplStatsdelayedmanifestconvertOpenAfun embedOpenAcc embedPreAccdoneyieldstepaccTypecompute' computeAcc generateDmapDunzipD backpermuteD transformD replicateDsliceDreshapeDzipWithDaletDaletD'applyDacondDaprjD isIdentityidentityreindexextendrestrict linearIndex$fSinkCunctation$fSimplifyCunctationfloatOutAccFromExpenableAccFusionconvertOffsetOfSegmentphasesPhaseconvertAccWithconvertAfunWith $fShow(->) $fShowExp $fShow(->)0 $fShowAccAccType arrayType preAccTypeexpType preExpTypesizeOfdelayedAccTypedelayedExpTypeEvalAccconfig evalOpenAfun evalOpenAcc evalAtupleunitOp generateOp transformOp reshapeOp replicateOpsliceOpmapOp zipWithOpfoldOpfold1Op foldSegOp fold1SegOpscanl1OpscanlOpscanl'OpscanrOpscanr1Opscanr'Op permuteOp backpermuteOp stencilOp stencil2Op evalPreExp evalPreFunevalPreOpenFunevalPreOpenExp evalTuple Applicative