yi      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~DB[2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)SafeH[2009..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneD#2Spawn an asynchronous action in a separate thread.Like  , but using  internally.Like  , but using  internally.RBlock the calling thread until the computation completes, then return the result.aTest whether the asynchronous computation has already completed. If so, return the result, else .*Cancel a running asynchronous computation. 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 ST,fJA 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 "      !"#$% 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 ...bNote that aside from the processor load metrics, counters are shared between all active backends.Registered rates: acc.load.llvm_nativeCurrent processor load (%) of the LLVM CPU backend. This only includes time spent executing Accelerate functions; compare this to the total processor load (e.g. via top) to estimate the productivity of the Accelerate program.acc.load.llvm_ptxCurrent processor load (%) of the GPU in the LLVM PTX backend. This only takes into account how much time the GPU spent executing Accelerate code, and does not consider the number of active cores during that time.Registered gauges: acc.gc.current_bytes_remoteMTotal number of bytes currently considered live in the remote address space.acc.gc.current_bytes_nurseryqTotal number of bytes allocated in the remote address space but not currently live (available for reallocation).Registered counters: acc.gc.bytes_allocated_local<Total number of bytes allocated in the local address space.acc.gc.bytes_allocated_remote=Total number of bytes allocated in the remote address space.acc.gc.bytes_copied_to_remotegTotal number of bytes copied from the host to the remote address space (e.g. from the CPU to the GPU).acc.gc.bytes_copied_from_remoteqTotal number of bytes copied from the remote address space back to the host (e.g. from the GPU back to the CPU). acc.gc.bytes_evicted_from_remoteTotal number of bytes evicted from the remote address space by the LRU memory manager, in order to make space for new allocations. A subset of acc.gc.bytes_copied_from_remote.acc.gc.num_gcsENumber of garbage collections of the remote address space performed.acc.gc.num_lru_evictCTotal number of evictions from the remote address space performed.(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.*7Allocated the number of bytes in the local memory space+!Allocated the number of bytes of new" memory in the remote memory space,6Copied data between the local and remote memory spaces-/Performed a major GC of the remote memory space.DPerformed an eviction of a remote array of the given number of bytes/01&'()*+23,45-./01 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_ 6789:;<=>?@ABCDEFGHIJKLM 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)NonevNShow a signed O. value using SI unit prefixes. In the call to: showFFloatSIBase prec base valIf prec is . the value is shown to full precision, and if prec is P 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.QThe Q 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.RThe R function outputs the trace message together with a time stamp from the IO monad. This sequences the output with respect to other IO actions.SThe S function behaves like Qp with the difference that the message is emitted to the eventlog, if eventlog profiling is enabled at runtime.T3Print a message prefixed with the current CPU time.UThe Uf function emits a message to the eventlog, if eventlog profiling is available and enabled at runtime. Compared to S, U7 sequences the event with respect to other IO actions.NQRSTU 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|VMExecute 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.VWH[2009..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None"#XIssue an internal error message'$internalError :: String -> String -> aYSThrow an error if the condition evaluates to False, otherwise evaluate the result.4$internalCheck :: String -> String -> Bool -> a -> aZKThrow 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 X\]Y^_Z[`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&';<=FNSTVifXGeneralised array index, which may index only in a subset of the dimensions of a shape.gSlice representation7Class of slice representations (which are nested pairs)hIndex representation7Class of index representations (which are nested pairs)i1Project the shape of a slice from the full shape.jYEnumerate all slices within a given bound. The innermost dimension changes most rapidly.See  for an example.k.number of dimensions (>= 0); rank of the arrayl-total number of elements in an array of this shapem empty shape.fnopgqrsthmuvlwxyzk{|}~ijfnopgqrsthklmvuwyzx|}~{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)SafeOz 55`[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)NoneDNjA 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. `[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)NoneA 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]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%0H[2015..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)Safe"#߭[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 &'+;=>?FTHConversion 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*! 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&'+-1;=FST AConstraint that values of these two types have the same bit widthSAll scalar typesT Bounded typesU Numeric typesVNon-numeric typesWFloating typesXIntegral 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.b  "#$%&'()*+,-.STUVWX     STUVWX     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&'01DFTVGADT 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 LifetimeS !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefg  "#$!%&'()*+,-./0123456789:;<=>?@ABCDEFhdicjbkal`m_n^o]p\q[rZsYtXuWvVwUxTySzR{Q|P}O~NMLKJIH[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&'+01;<=FNSTV/Generalised array division, like above but use for splitting an array into many subarrays, as opposed to extracting a single subarray.Y$Slices, aka generalised indices, as nQ-tuples and mappings of slice indices to slices, co-slices, and slice dimensions^.Shapes and indices of multi-dimensional arraysNumber of dimensions of a shape or index (>= 0).2Total number of elements in an array of the given shape.Empty shape.,Magic value identifying elements ignored in permute.$Yield the intersection of two shapesYield the union of two shapesrMap 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). Inverse of .Iterate 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. Variant of  without an initial value)Convert a minpoint-maxpoint index into a shape. Convert a shape into a minpoint-maxpoint index.(Convert a shape to a list of dimensions.*Convert a list of dimensions into a shape.,The slice index for slice specifier 'Any sh'JThe slice index for specifying a slice with only the Z component projectedi/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.j"Vectors are one-dimensional arraysk$Scalars arrays hold a single elementl)Dense, regular, multi-dimensional arrays.The l 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 l 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, g for one-dimensional js, f) 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 ^Q is the fastest varying). The allowable array element types are members of the n" 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 u and (s)@Nested tuples of all of these, currently up to 15-elements wide. Note that lj 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 l type.Tuple reification.Tuples of Arrays. Note that this carries the m! class constraint rather than n" in the case of tuples of scalars.AWe represent tuples as heterogeneous lists, typed by a type list.EThe tuple representation is equivalent to the product representation.mm) consists of nested tuples of individual lcs, currently up to 15-elements wide. Accelerate computations can thereby return multiple results.nThe n 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 u and (s)?Nested tuples of all of these, currently up to 15-elements wideAdding new instances for n~ 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-accelerateType 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.o#Marker for arbitrary dimensions in   and ! descriptors.o< can be used in the leftmost position of a slice instead of uE, indicating that any dimensionality is admissible in that position.See   and ! for examples.q Marker for entire dimensions in   and ! descriptors.Occurrences of qZ indicate the dimensions into which the array's existing extent will be placed unchanged.See   and ! for examples.s.Increase an index rank by one dimension. The s7 operator is used to construct both values and types.u Rank-0 indexConvenience functionsYield an array's shapeArray indexingwVCreate an array from its representation function, applied at each index of the array.DCreate a vector from the concatenation of the given list of vectors..Creates a new, uninitialized Accelerate array.x.Convert elements of a list into an Accelerate l.*This will generate a new multidimensional ly 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.yConvert an accelerated l to a list in row-major order.!Nicely format a shape as a string1Project the shape of a slice from the full shape.YEnumerate 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 ]gYZ[\]^_`abcdefghijklmnopqrstuvwxyYZ[\]^lmnopqrstuvs3t39 "`[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&'+1>?FOQTV.#{[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+FT 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.Cast a remote pointer.3Returns the total remote memory available in bytes./Returns, in bytes, the available remote memory."The chunk allocation size (bytes)./Matches array element types to primitive types. $[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&'01;<=>?FQSTV;Primitive 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  classOperations on stencils7Boundary condition specification for stencil operations"Vanilla stencil boundary conditiondCollective 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{|}~ B      !"#$%&'()*+,-./0123456789:;<=>EF?@DGHIJKLMNOPQRCSTUBVWAXYZ[\]^_`abefgcdopnqrstuvjwxyzki{m|}~hl%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&'+;=FOQSTVOReplace the first variable with the given expression. The environment shrinks.Replace an expression that uses the top environment variable with another. The result of the first is let bound into the second.Composition of unary functions.   &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&'V'[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&'01;<=>?FSTVK'{7Boundary condition specification for stencil operationsScalar 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 knot}Accelerate 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 l or a tuple of m"). 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 (j&s) of values, and produces a single (k?) 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 / and 0x, 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.z{|     } !"#$%&'()*+,-./01234~56789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~z{|     }00001H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None ;<=>?FSTc DA limited subset of types which can be lifted, can also be unlifted.Unlift 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.The class of types e which can be lifted into c.jAn 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))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.Lift a unary function into |.Lift 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. 2H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+;<=gMBasic numeric classKLMN3H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+;<=k,Fractional numbers, supporting real divisionGH4H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+;<=o<Trigonometric and hyperbolic functions and related functions;<>=?/0123456789:@5H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None +;<=>?vc(Accelerate lacks an arbitrary-precision 67 type, which the standard 68 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 types9H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None;<=zThe  class defines equality  and inequality $ for scalar Accelerate expressions.For convenience, we include n 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 negation4432: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;<=~The $ class for totally ordered datatypes4444;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+;<=<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+;<=#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  =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+;<=*Operations over sequentially ordered 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+;<=l.Integral numbers, supporting integral divisionABCDEF[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 %+<FSTV8eMake 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 m: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 of can be used in the slice specification to match against some arbitrary dimension. For example, here o/ 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, o and q 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 (j") 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 ?@, 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, J is a no-op. 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 (qs) 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 q):&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 q6s) returns a single element (zero dimensional array).$slice (use mat) (lift (Z :. 4 :. 2)) Scalar Z [42] The marker oa can be used in the slice specification to match against some arbitrary (lower) dimension. Here o' 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, o and q 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]JApply the given function element-wise to an array. Denotationally we have: /map f [x1, x2, ... xn] = [f x1, f x2, ... f xn]let xs = fromList (Z:.10) [0..]xs&Vector (Z :. 10) [0,1,2,3,4,5,6,7,8,9]map (+1) (use xs)'Vector (Z :. 10) [1,2,3,4,5,6,7,8,9,10]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.!let xs = fromList (Z:.3:.5) [0..]xsMatrix (Z :. 3 :. 5) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13,14]"let ys = fromList (Z:.5:.10) [1..]ysMatrix (Z :. 5 :. 10)! [ 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]zipWith (+) (use xs) (use ys)Matrix (Z :. 3 :. 5) [ 1, 3, 5, 7, 9, 16,18,20,22,24, 31,33,35,37,39]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 AQ, 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)#let mat = fromList (Z:.4:.10) [0..]scanl (+) (use mat)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.The combination function is given the new value being permuted as its first argument, and the current value of the array as its second.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]|As a second example, note that the dimensionality of the source and destination arrays can differ. In this way, we can use J to create an identity matrix by overwriting elements along the diagonal: identity :: Num a => Exp Int -> Acc (Array DIM2 a) identity n = let zeros = fill (index2 n n) 0 ones = fill (index1 n) 1 in permute const zeros (\(unindex1 -> i) -> index2 i i) ones identity 5Matrix (Z :. 5 :. 5) [1,0,0,0,0, 0,1,0,0,0, 0,0,1,0,0, 0,0,0,1,0, 0,0,0,0,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.TIf the array of default values is only used once, it will be updated in-place.: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 ?B 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: Js33 :: 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 .}Boundary condition where elements of the stencil which would be out-of-bounds are instead clamped to the edges of the array.8In the following 3x3 stencil, the out-of-bounds element b, will instead return the value at position c: T +------------+ |a | b|cd | |e | +------------+ZStencil boundary condition where coordinates beyond the array extent are instead mirrored8In the following 5x3 stencil, the out-of-bounds element c, will instead return the value at position d, and similarly the element at b will return the value at e: T +------------+ |a | bc|def | |g | +------------+dStencil boundary condition where coordinates beyond the array extent instead wrap around the array.fIn the following 3x3 stencil, the out of bounds elements will be read as in the pattern on the right.  a bc +------------+ +------------+ d|ef | |ef d| g|hi | -> |hi g| | | |bc a| +------------+ +------------+\Stencil boundary condition where the given function is applied to any outlying coordinates.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 in 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-For an example use of this operation see the C function.&An array-level if-then-else construct. Enabling the RebindableSyntaxK extension will allow you to use the standard if-then-else syntax instead.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.The innermost dimension (right-most component of the shape) is the index of the array which varies most rapidly, and corresponds to elements of the array which are adjacent in memory.Another way to think of this is, for example when writing nested loops over an array in C, this index corresponds to the index iterated over by the innermost nested loop.,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. Enabling the RebindableSyntaxK extension will allow you to use the standard if-then-else syntax instead.~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. combination 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 valueMz{|}~19 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 %&'+<V<6Return 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. 756888888DH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+<>?E,)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,-,-EH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None %+7;<=V[.SEfficient, machine-independent access to the components of a floating-point number/4The radix of the representation (often 2) (constant)0The number of digits of / in the significand (constant)1@The lowest and highest values the exponent may assume (constant)2AReturn the significand and an appropriately scaled exponent. If (m,n) = 2 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) <= L m < b^d, where d = 0 x.3 Inverse of 24'Corresponds to the second component of 25&Corresponds to the first component of 26AMultiply a floating point number by an integer power of the radix76 if the argument is an IEEE "not-a-number" (NaN) value89 if the argument is an IEEE infinity or negative-infinity9E if the argument is too small to be represented in normalized format:) if the argument is an IEEE negative zero;1 if the argument is an IEEE floating point number<UA 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]../0123456789:;<.//0011233456789:;;<FH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+;<=a=vName the upper and lower limits of a type. Types which are not totally ordered may still have upper and lower bounds.IJ=GH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NonecTJI@?>=<;:9876543210/HGFEDCBAMNLK,-./0123456789:;<=[2015..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+;<=>?FTVr>.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 >?@ABCDE CDAB@>?EHc[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 &';=OQSTVvIE[2010..2011] Ben Lever [2010..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None&'STV~\Calculate 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.JB[2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None &'OQV^KH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None &'OQSTVLH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None"#&'+;=FOQSTVhReplace all occurrences of the first variable with the given array expression. The environment shrinks.4MH[2015..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None"#%&';=NOQV5Generate a dependency graph for the given computation1Generate a dependency graph for an array function         Nc[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.G/01&'()*+23,45-.6789:;<=>NQRSTUVWOH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%&'OQV  P[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&'01;=FOSTVԤ!'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.'aConvert an open array expression to de Bruijn form while also incorporating sharing information.(Convert 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).)Convert a boundary condition*\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.+^Convert a closed scalar expression to de Bruijn form while incorporating sharing information.,Convert 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).-Convert a tuple expression.Convert a unary functions/Convert a binary functions0 Convert a unary stencil function1!Convert a binary stencil function2Recover 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 3 s of all M 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  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.)%'recover sharing of array computations ?'recover sharing of scalar expressions ?*recover sharing of sequence computations ?3always float array computations out of expressions?+'recover sharing of scalar expressions ?expression to be converted4567%&*+89:;<=>?@ABCDEFGH3IJKLMNOPQRSTU45V67WXYZ[\!"#$Q[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)Noned]Create 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 nurserya1The total number of bytes retained by the nurserybcd]^_`aefcdR[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%&'+DKOQV g:An untyped reference to an array, similar to a StableName.h5Create a new memory table from host to remote arrays.$The function supplied should be the i for the remote pointers being stored. This function will be called by the GC, which typically runs on a different thread. Unlike the i in ,, this function cannot depend on any state.jELook for the remote pointer corresponding to a given host-side array.kjAllocate a new device array to be associated with the given host-side array. This may not always use the k 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,  is returned.iDeallocate the device array associated with the given host-side array. Typically this should only be called in very specific circumstances.lDeallocate the device array associated with the given StableArray. This is useful for other memory managers built on top of the memory table.mRecord 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.ngInitiate garbage collection and mark any arrays that no longer have host-side equivalents as reusable.oCall iH on all arrays that are not currently associated with host-side arrays.p Initiate garbage collection and iG any remote arrays that no longer have matching host-side equivalents.q Make a new g.rAMake a weak pointer using an array as a key. Unlike the standard /, this guarantees finalisers won't fire early. gshjkilmpqrgtuvswS{[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 &')+OQV+xA 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.y(Returns true when the task has finished.z5Create 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  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 yw 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 that the array 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.dIf this function is called on an array that is already contained within the cache, this is 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.%Was the array allocated successfully? xyz|}{~xyT{[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/~xyz|}{~Uc[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&';=V3Show instances ---------------    Vc[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&'QV:CReify 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 shapeWH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None %&'NOQSTV>(XH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None"#%&';<=OSTVA~146Yw[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%&'+.;<=OQSTVVIApply 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.9Apply the fusion transformation to a closed de Bruijn AST@Apply the fusion transformation to a function of array argumentsGApply 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...ZH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None"#;<=h2 &Recover sharing of array computations?&Recover sharing of scalar expressions?)Recover sharing of sequence computations?nAre array computations floated out of expressions irrespective of whether they are shared or not? Requires .mFuse array computations? This also implies simplifying scalar expressions. NOTE: currently always enabled.9Convert segment length arrays into segment offset arrays?sThe default method of converting from HOAS to de Bruijn; incorporating sharing recovery and fusion optimisation.uConvert a closed array expression to de Bruijn form while also incorporating sharing observation and array fusion.gConvert a unary function over array computations, incorporating sharing observation and array fusionZConvert a closed scalar expression, incorporating sharing observation and optimisation.WConvert closed scalar functions, incorporating sharing observation and optimisation.;67[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 &'FOQTVtKDetermine 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 ?n[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*+;<=>?FOSTVeO For use with -XRebindableSyntax, this class provides Q( lifted to both scalar and array types.R Pair each element with its indexlet xs = fromList (Z:.5) [0..]indexed (use xs)RVector (Z :. 5) [(Z :. 0,0.0),(Z :. 1,1.0),(Z :. 2,2.0),(Z :. 3,3.0),(Z :. 4,4.0)]"let mat = fromList (Z:.3:.4) [0..]indexed (use mat)Matrix (Z :. 3 :. 4)M [(Z :. 0 :. 0,0.0),(Z :. 0 :. 1,1.0), (Z :. 0 :. 2,2.0), (Z :. 0 :. 3,3.0),M (Z :. 1 :. 0,4.0),(Z :. 1 :. 1,5.0), (Z :. 1 :. 2,6.0), (Z :. 1 :. 3,7.0),M (Z :. 2 :. 0,8.0),(Z :. 2 :. 1,9.0),(Z :. 2 :. 2,10.0),(Z :. 2 :. 3,11.0)]S;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 no-op.l?Take an array of triples and return three arrays, analogous to k.mATake an array of quadruples and return four arrays, analogous to k.n?Take an array of 5-tuples and return five arrays, analogous to k.o>Take an array of 6-tuples and return six arrays, analogous to k.p@Take an array of 7-tuples and return seven arrays, analogous to k.q@Take an array of 8-tuples and return eight arrays, analogous to k.r@Take an array of 8-tuples and return eight arrays, analogous to k.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 does not need a default value. The first argument must be an  associative function.uHCheck if all elements along the innermost dimension satisfy a predicate.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]all even (use mat)(Vector (Z :. 4) [False,False,True,False]vKCheck if any element along the innermost dimension satisfies the predicate.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]any even (use mat)&Vector (Z :. 4) [True,True,True,False]w8Check if all elements along the innermost dimension are .x6Check if any element along the innermost dimension is .ynCompute the sum of elements along the innermost dimension of the array. To find the sum of the entire array,  it first."let mat = fromList (Z:.2:.5) [0..]Vector (Z :. 2) [10,35]zzCompute the product of the elements along the innermost dimension of the array. To find the product of the entire array,  it first."let mat = fromList (Z:.2:.5) [0..]Vector (Z :. 2) [0,15120]{}Yield the minimum element along the innermost dimension of the array. To find find the minimum element of the entire array,  it first.&The array must not be empty. See also .<let mat = fromList (Z :. 3 :. 4) [1,4,3,8, 0,2,8,4, 7,9,8,8]matMatrix (Z :. 3 :. 4) [ 1, 4, 3, 8, 0, 2, 8, 4, 7, 9, 8, 8]minimum (use mat)Vector (Z :. 3) [1,0,7]|xYield the maximum element along the innermost dimension of the array. To find the maximum element of the entire array,  it first.&The array must not be empty. See also .<let mat = fromList (Z :. 3 :. 4) [1,4,3,8, 0,2,8,4, 7,9,8,8]matMatrix (Z :. 3 :. 4) [ 1, 4, 3, 8, 0, 2, 8, 4, 7, 9, 8, 8]maximum (use mat)Vector (Z :. 3) [8,8,9]}4Left-to-right pre-scan (aka exclusive scan). As for scan!, the first argument must be an  associative# function. Denotationally, we have:  prescanl f e = afst . scanl' f e"let vec = fromList (Z:.10) [1..10]prescanl (+) 0 (use vec),Vector (Z :. 10) [0,1,3,6,10,15,21,28,36,45]~&Left-to-right post-scan, 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) [43,45,48,52,57,63,70,78,87,97]4Right-to-left pre-scan (aka exclusive scan). As for scan!, the first argument must be an  associative# function. Denotationally, we have:  prescanr f e = afst . scanr' f e%Right-to-left postscan, a variant of 1 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.let zeros = fill (Z:.10) 0:Vector (Z :. 10) [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]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. Enabling the RebindableSyntaxK extension will allow you to use the standard if-then-else syntax instead.An infix version of  . If the predicate evaluates to A, the first component of the tuple is returned, else the second. Enabling the RebindableSyntaxK extension will allow you to use the standard if-then-else syntax instead.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.x: starty: step'index of source at each index to gather source valuessource 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 valuenOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~OPQ500[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"#%&'<FOQSTVFRun a complete embedded array program using the reference interpreter.This is 1 specialised to an array program of one argument..Prepare and execute an embedded array program.m}}m[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 ^.WIJ;<>=?/0123456789:@GHABCDEFKLMN  "#$%&'()*+,-.OPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~,-./0123456789:;<=OPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\}lmkjinuvsthgfedcba`_^YZ[\]qropOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~z{|=JINMLKFEDCBAHG@:9876543210/?=><;.//0011233456789:;;<,-~wxyORQP   -.%&'()*+,"#$SUTXWV[2016..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None +;<=>?FTV !  ! [2016..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None &'+;<=STc' 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.\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 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.]^_]`a]`b]cd]`e]^f]^g]^h]^ijkljkmjknjkojkp]qr]qs]qt]qujkv]wx]wy]wz]w{jk|jk}]~]~]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]c]c]c]c]c]c]c]c]]]`]`]`]`]^]^]]'''''1111111111123455999999:::::::<<<<<<<<< >    !)0 (.+, !"#$*-%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~DDEEEEEEEEEEEEEEEF?????????????????????????????/?????????????????????????????????????????B??????C???????????????????@??      !"#AA$%&'()*+,-]./0]1234]^5677 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 { | } ~                                   ]]^       93F129]     ]w]w]w !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFFGGHHIJKLMNOPQR]STUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~9F31286"""""""""""""""##########$$ $ $$ $ $ $$$$$$$$$$$$$$$$$$$$$$ $!$"$#$$$%$&$'$($)$*$+$,$-$.$/$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${$|$-$}$~$$$$$$$$$A$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%&&' ']''''}'~''''''^'_'' ''b'c'd'e'f'g'j'k'l'm'n'o'p'q'r''''''''A''''''''''''''''''''''''''''''''''''''''''''''''' ' ' ' ' ''''''''''''''''''' '!'"'#'$'%'&'''(')'*'+','-'.'/'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=uvwx]cHyHzHHHH{H|H}H~HHHHHHHHHHHHHHIIIJJJJJJJ]]KKKKKKKKKKKKKKKKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMNNNNOOOOOOOOOPPPPPPPPPPPPPPPPPPPP~PPPPPPPPPPP P P P P P P P PPPPPPPPPPPPPPPPPPPPPPQQQQ Q9Q!Q"Q"QQR#RR$RR%R&R'R(R)R*R+R,R-R#R.R.R-S/S0SS$S1S%S'S*S-S2S2S3S4S5S6S7S-U8V9V:V;V<V=W>X?XRX@X@XAXBXCXDXEXFXGXHYIYYYYJYKYLYMYNYNZZZZOZPZQZRZZZZZSZSZTZU[V[W[X[Y[Z[[[\[][^?_?`?a?b?c?d}~]^e\f\\g\\fh)accelerate-1.1.0.0-KGurD6P5LbeApn2BeqEOaxData.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.Array.Accelerate.Analysis.Hash.THData.Array.Accelerate.Async!Data.Array.Accelerate.Debug.Flags&Data.Array.Accelerate.Debug.Monitoring!Data.Array.Accelerate.Debug.Stats!Data.Array.Accelerate.Debug.Trace!Data.Array.Accelerate.Debug.TimedData.Array.Accelerate.Error*Data.Array.Accelerate.Array.Representation!Data.Array.Accelerate.Array.Sugar enumSlicesData.Array.Accelerate.FullListData.Array.Accelerate.LifetimeSystem.Mem.WeakfinalizeWeak"Data.Array.Accelerate.Array.Unique*Data.Array.Accelerate.Pretty.Graphviz.Type+Data.Array.Accelerate.Pretty.Graphviz.MonadData.Array.Accelerate.ProductData.Array.Accelerate.Type Data.Array.Accelerate.Array.DatausetoSeqData.Array.Accelerate.Languageslice replicate"Data.Array.Accelerate.Array.Lifted(Data.Array.Accelerate.Array.Remote.ClassData.Array.Accelerate.AST(Data.Array.Accelerate.Trafo.Substitution#Data.Array.Accelerate.Trafo.RewriteData.Array.Accelerate.Smartmapgenerate backpermutefoldscanlstencilzipWithunzipreshapeData.Array.Accelerate.Lift!Data.Array.Accelerate.Classes.Num(Data.Array.Accelerate.Classes.Fractional&Data.Array.Accelerate.Classes.Floating(Data.Array.Accelerate.Classes.ToFloatingPreludeRational realToFrac Data.Array.Accelerate.Classes.Eq!Data.Array.Accelerate.Classes.Ord"Data.Array.Accelerate.Classes.Real&Data.Array.Accelerate.Classes.RealFrac"Data.Array.Accelerate.Classes.Enum&Data.Array.Accelerate.Classes.IntegralData.Array.Accelerate.PreludetheFold transposecompute*Data.Array.Accelerate.Classes.FromIntegral'Data.Array.Accelerate.Classes.RealFloat%Data.Array.Accelerate.Classes.BoundedData.Array.Accelerate.Classes"Data.Array.Accelerate.Pretty.Print&Data.Array.Accelerate.Analysis.Stencil#Data.Array.Accelerate.Analysis.Hash$Data.Array.Accelerate.Analysis.Match Data.Array.Accelerate.Trafo.Base%Data.Array.Accelerate.Pretty.GraphvizData.Array.Accelerate.Debug"Data.Array.Accelerate.Trafo.Shrink#Data.Array.Accelerate.Trafo.Sharing*Data.Array.Accelerate.Array.Remote.Nursery(Data.Array.Accelerate.Array.Remote.Table&Data.Array.Accelerate.Array.Remote.LRU"Data.Array.Accelerate.Array.RemoteData.Array.Accelerate.Pretty$Data.Array.Accelerate.Analysis.Shape#Data.Array.Accelerate.Trafo.Algebra$Data.Array.Accelerate.Trafo.Simplify"Data.Array.Accelerate.Trafo.FusionData.Array.Accelerate.Trafo#Data.Array.Accelerate.Analysis.Type Data.AtomicbaseGHC.Base$GHC.Num fromInteger-GHC.Real fromRationalnegatememptymappendmconcatMonoidghc-prim GHC.TypesBoolCharDoubleFloatIntGHC.IntInt8Int16Int32Int64WordGHC.WordWord8Word16Word32Word64FalseTrue Data.Complex:+Complex Data.Monoid<>getSumSum getProductProductForeign.C.TypesCCharCSCharCUCharCShortCUShortCIntCUIntCLongCULongCLLongCULLongCFloatCDouble GHC.FloatatanhacoshasinhtanhcoshsinhatanacosasintancossinlogBase**sqrtlogexppidivModquotRemmoddivremquotrecip/GHC.EnummaxBoundminBoundsignumabs*+.constGHC.Err undefinederrorIsScalar IsBoundedIsNumIsNonNum IsFloating IsIntegralSlice SliceShape CoSliceShape FullShape sliceIndexShapeDIM9DIM8DIM7DIM6DIM5DIM4DIM3DIM2DIM1DIM0SegmentsVectorScalarArrayArraysEltAnyAll:.Z fromFunctionfromListtoListStencilBoundaryExpAccconstantUnliftunliftLiftPlainliftlift1lift2lift3ilift1ilift2ilift3Num FractionalFloating ToFloating toFloatingEq==/=&&||notOrd<><=>=minmaxRealFracproperFractiontruncateroundceilingfloordiv'mod'divMod'Integral Stencil5x5x5 Stencil3x5x5 Stencil5x3x5 Stencil5x5x3 Stencil3x3x5 Stencil3x5x3 Stencil5x3x3 Stencil3x3x3 Stencil5x5 Stencil3x5 Stencil5x3 Stencil3x3Stencil9Stencil7Stencil5Stencil3unitfold1foldSegfold1Segscanl'scanl1scanrscanr'scanr1permutestencil2clampmirrorwrapfunction foreignAcc foreignExp>->acondawhile indexHead indexTailtoIndex fromIndex intersectcondwhile!!!shapesize shapeSizesubtractevenoddgcdlcm^^^ordchr boolToIntbitcastignore FiniteBits finiteBitSizecountLeadingZeroscountTrailingZerosBits.&..|.xor complementshiftrotatezeroBitsbitsetBitclearBit complementBittestBitisSignedshiftL unsafeShiftLshiftR unsafeShiftRrotateLrotateRpopCount $fBitsCUShort $fBitsCShort $fBitsCULLong $fBitsCLLong $fBitsCULong $fBitsCLong $fBitsCUInt $fBitsCInt $fBitsWord64 $fBitsWord32 $fBitsWord16 $fBitsWord8 $fBitsWord $fBitsInt64 $fBitsInt32 $fBitsInt16 $fBitsInt8 $fBitsInt $fBitsBool$fFiniteBitsCUShort$fFiniteBitsCShort$fFiniteBitsCULLong$fFiniteBitsCLLong$fFiniteBitsCULong$fFiniteBitsCLong$fFiniteBitsCUInt$fFiniteBitsCInt$fFiniteBitsWord64$fFiniteBitsWord32$fFiniteBitsWord16$fFiniteBitsWord8$fFiniteBitsWord$fFiniteBitsInt64$fFiniteBitsInt32$fFiniteBitsInt16$fFiniteBitsInt8$fFiniteBitsInt$fFiniteBitsBool FromIntegral fromIntegral RealFloat floatRadix floatDigits floatRange decodeFloat encodeFloatexponent significand scaleFloatisNaN isInfiniteisDenormalizedisNegativeZeroisIEEEatan2Bounded 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++filtergatherscatterreversetakedropinittailslit?|?caseofiteratesfoldlfstafstsndasndcurryuncurryindex0index1unindex1index2unindex2index3unindex3nulllengthrunrun1runN 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 $fFunctorFoldhashQ hashWithSaltQasyncasyncOn GHC.Conc.SyncforkOn asyncBoundControl.ConcurrentforkOSwaitpollNothingcancelAsyncaccInitwhenunlessFlagsMode acc_sharingdebug_ccdump_asmdump_ccdump_dot dump_execdump_gc dump_gc_statsdump_ld dump_phases dump_sched dump_sharingdump_simpl_dotdump_simpl_iterationsdump_simpl_statsdump_vectorisation exp_sharing fast_math flush_cache force_recompfusionsimplifyverbose queryFlagsetFlag clearFlagsetFlag'setFlags clearFlags _acc_sharing _exp_sharing_fusion _simplify_unfolding_use_threshold _flush_cache _force_recomp _fast_math_verbose _dump_phases _dump_sharing_dump_simpl_stats_dump_simpl_iterations_dump_vectorisation _dump_dot_dump_simpl_dot_dump_gc_dump_gc_stats _debug_cc_dump_cc_dump_ld _dump_asm _dump_exec _dump_schedOptKindNoArgIntArgFlagSpecOption DebugFlagdefbeginMonitoringinitAccMetrics withProcessoraddProcessorTimedidAllocateBytesLocaldidAllocateBytesRemotedidCopyBytesToRemote didRemoteGC didEvictBytes ProcessorNativePTXincreaseCurrentBytesRemotedecreaseCurrentBytesRemotedidCopyBytesFromRemotesetCurrentBytesNurseryinline ruleFired knownBranch betaReduce substitutionsimplifierDone fusionDoneresetSimplCount simplCountTickInline RuleFired KnownBranch BetaReduce SubstitutionSimplifierDone FusionDoneId SimplStatsSimpleDetailticksdetailsshowFFloatSIBaseJusttracetraceIO traceEvent putTraceMsg traceEventIOtimedelapsed internalError internalCheck indexCheckinternalWarning boundsError unsafeError boundsCheck unsafeCheck boundsWarning unsafeWarningCheckBoundsUnsafeInternal SliceIndex sliceShaperankemptySliceNilSliceAll SliceFixedunioniter shapeToListiter1 rangeToShape shapeToRange listToShapeListNilConsFullListFLcons singletonlookup lookupDeletemapM_LTFLifetime newLifetime withLifetime touchLifetime addFinalizermkWeakunsafeGetValue mkWeakPtr UniqueArraynewUniqueArraywithUniqueArrayPtrunsafeUniqueArrayPtrGHC.ForeignPtrunsafeForeignPtrToPtrtouchUniqueArray uniqueArrayIduniqueArrayDataEdgeVertexPortLabelNodeIdNode StatementGNEGraphTreeLeafForestppGraph ppSubgraph ppStatementppEdgeppVertexppNode ppNodeTreeppNodeIdDotStatedotNodesdotEdgesdotGraphfreshDot emptyStaterunDotevalDotexecDotmkLabelmkNodeIdmkGraph mkSubgraph IsProductProdRTupleIdxProdReprfromProdtoProdprod ProdRunit ProdRsnoc ZeroTupIdx SuccTupIdx BitSizeEq ScalarType BoundedTypeNumType NonNumType FloatingType IntegralType byteSwap64 byteSwap32 byteSwap16BitSize 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 ArrayEltRArrayEltMutableArrayData ArrayData runArrayDataregisterForeignPtrAllocator!mallocPlainForeignPtrBytesAlignedmallocForeignPtr HTYPE_INT HTYPE_WORD HTYPE_LONGHTYPE_UNSIGNED_LONG HTYPE_CCHAR ArrayPtrstouchArrayDataarrayEltunsafeIndexArrayDataptrsOfArrayData newArrayDataunsafeReadArrayDataunsafeWriteArrayDataunsafeFreezeArrayDataptrsOfMutableArrayData ArrayEltRunit ArrayEltRint ArrayEltRint8ArrayEltRint16ArrayEltRint32ArrayEltRint64 ArrayEltRwordArrayEltRword8ArrayEltRword16ArrayEltRword32ArrayEltRword64ArrayEltRcshortArrayEltRcushort ArrayEltRcintArrayEltRcuintArrayEltRclongArrayEltRculongArrayEltRcllongArrayEltRcullongArrayEltRfloatArrayEltRdoubleArrayEltRcfloatArrayEltRcdouble ArrayEltRbool ArrayEltRcharArrayEltRccharArrayEltRcscharArrayEltRcuchar ArrayEltRpair GArrayDataAD_UnitAD_IntAD_Int8AD_Int16AD_Int32AD_Int64AD_WordAD_Word8 AD_Word16 AD_Word32 AD_Word64 AD_CShort AD_CUShortAD_CIntAD_CUIntAD_CLong AD_CULong AD_CLLong AD_CULLongAD_Float AD_Double AD_CFloat AD_CDoubleAD_BoolAD_CharAD_CChar AD_CSChar AD_CUCharAD_Pair fstArrayData sndArrayData pairArrayDataD: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()0Division sliceAnyIndexsliceNoneIndexTupleRAtupleTuple TupleReprEltReprDivideSplitsingletonScalarType concatVectors allocateArray showShape DivisionSlice slicesIndexNilAtupSnocAtupNilTupSnocTuparraysflavourtoArrfromArr ArraysFlavour ArraysFunit ArraysFarray ArraysFtupleArraysR ArraysRunit ArraysRarray ArraysRpairIsAtupleArrReprForeign strForeign liftForeigntoEltfromElteltTypeIsTuple fromTupletoTuple liftToElt liftToElt2 sinkFromElt sinkFromElt2 fromAtupletoAtupletuple IsConstrainedIsC LiftedArrayLiftedTupleReprVector' isArraysFlat elements'shapes'empty'length'drop'vec2Vec'toList' fromList' RemoteMemory RemotePtr mallocRemote pokeRemote peekRemote castRemotePtrtotalRemoteMemavailableRemoteMemremoteAllocationSizePrimEltPrimFun PrimConst PreOpenExpPreExpOpenExpFunPreFunOpenFun PreOpenFunStencilR PreBoundary PreOpenAccAfunPreAfun PreOpenAfunLiftAcc NFDataAccPrimAddPrimSubPrimMulPrimNegPrimAbsPrimSigPrimQuotPrimRem PrimQuotRemPrimIDivPrimMod PrimDivModPrimBAndPrimBOrPrimBXorPrimBNot PrimBShiftL PrimBShiftR PrimBRotateL PrimBRotateR PrimPopCountPrimCountLeadingZerosPrimCountTrailingZerosPrimFDiv PrimRecipPrimSinPrimCosPrimTanPrimAsinPrimAcosPrimAtanPrimSinhPrimCoshPrimTanh PrimAsinh PrimAcosh PrimAtanhPrimExpFloatingPrimSqrtPrimLogPrimFPow PrimLogBase PrimTruncate PrimRound PrimFloor PrimCeiling PrimAtan2 PrimIsNaNPrimIsInfinitePrimLtPrimGtPrimLtEqPrimGtEqPrimEqPrimNEqPrimMaxPrimMinPrimLAndPrimLOrPrimLNotPrimOrdPrimChr PrimBoolToIntPrimFromIntegralPrimToFloating PrimCoerce PrimMinBound PrimMaxBoundPrimPiConstUnionLetVarPrjIndexNil IndexCons IndexHead IndexTailIndexAny IndexSlice IndexFullToIndex FromIndexCondWhilePrimAppIndex LinearIndex ShapeSize IntersectBodyLam StencilRunit3 StencilRunit5 StencilRunit7 StencilRunit9 StencilRtup3 StencilRtup5 StencilRtup7 StencilRtup9ConstantFunctionClampMirrorWrapPermuteMapUnitAletAvarAprjApplyAforeignAcondAwhileUseReshapeGenerate Transform ReplicateZipWithFold1FoldSegFold1SegScanlScanl'Scanl1ScanrScanr'Scanr1 BackpermuteStencil2OpenAccOpenAfunAbodyAlamValEltEmptyEltPushEltValEmptyPushIdxZeroIdxSuccIdxidxToInt tupleIdxToIntprjprjEltrnfPreOpenAfun rnfPreOpenAcc rnfPreOpenFun rnfPreOpenExpliftIdx liftTupleIdxliftPreOpenAfunliftPreOpenAccliftPreOpenFunliftPreOpenExp liftArraysliftSliceIndex liftPrimConst liftPrimFun liftConst showPreAccOp showPreExpOp substitutecompose RebuildAcc:?>SinkExpweakenESinkweaken:> RebuildTupunRTupRebuildableAccRebuildableExprebuildErebuildPartialE RebuildableAccClorebuildPartialrebuildAsubTopsubAtop strengthen strengthenEIdxAIAunIA SyntacticAccavarInaccOut weakenAccIdxEIEunIE SyntacticExpvarInexpOut weakenExp weakenExpAccIdentity runIdentityconvertSegmentsconvertSegmentsAfunPreAccGHC.ShowShow StencilRepr stencilPrjTagAtagPipeLevelatup2atup3atup4atup5atup6atup7atup8atup9atup10atup11atup12atup13atup14atup15unatup2unatup3unatup4unatup5unatup6unatup7unatup8unatup9unatup10unatup11unatup12unatup13unatup14unatup15tup2tup3tup4tup5tup6tup7tup8tup9tup10tup11tup12tup13tup14tup15untup2untup3untup4untup5untup6untup7untup8untup9untup10untup11untup12untup13untup14untup15 mkMinBound mkMaxBoundmkPimkSinmkCosmkTanmkAsinmkAcosmkAtanmkSinhmkCoshmkTanhmkAsinhmkAcoshmkAtanh mkExpFloatingmkSqrtmkLogmkFPow mkLogBasemkAddmkSubmkMulmkNegmkAbsmkSigmkQuotmkRem mkQuotRemmkIDivmkModmkDivModmkBAndmkBOrmkBXormkBNot mkBShiftL mkBShiftR mkBRotateL mkBRotateR mkPopCountmkCountLeadingZerosmkCountTrailingZerosmkFDivmkRecip mkTruncatemkRoundmkFloor mkCeilingmkAtan2mkIsNaN mkIsInfinitemkLtmkGtmkLtEqmkGtEqmkEqmkNEqmkMaxmkMinmkLAndmkLOrmkLNotmkOrdmkChrmkFromIntegral mkToFloating mkBoolToInt mkBitcastmkUnsafeCoerce$$$$$$$$$$$$$$RealEnum integer-gmpGHC.Integer.TypeInteger PrettyEnv prettyEnv PrettyAcc prettyOpenAccprettyOpenAfun prettyOpenFun prettyOpenExpprettyPreOpenAccprettyPreOpenAfun prettyPreFunprettyPreOpenFun prettyPreExpprettyPreOpenExpprettyTupleIdx prettyPrim prettyArraysnoParenssizeEnvoffsets positionsRoffsets2HashAcc hashOpenAcchashPreOpenAcc hashOpenExphashPreOpenExphashPreOpenFuncommutesData.Type.Equality:~:ReflMatchAcc matchOpenAccmatchPreOpenAcc matchOpenAfunmatchPreOpenAfun matchOpenExpmatchPreOpenExp matchOpenFunmatchPreOpenFunmatchIdx matchPrimFun matchPrimFun'matchTupleTypematchScalarType matchNumTypematchIntegralTypematchFloatingTypeinlineA SupplementBaseSupPushSupExtendBaseEnvPushEnvGammaEmptyExpPushExpDelayedOpenAccDelayedManifestextentDindexD linearIndexDDelayedOpenFunDelayedOpenExpDelayedOpenAfun DelayedFun DelayedExp DelayedAfun DelayedAccMatchmatchKit prettyAcchashAccmatchAccinjectextract fromOpenAcckmap fromOpenAfunhashDelayedOpenAccmatchDelayedOpenAccincExpprjExp weakenGamma1 sinkGamma lookupExpappendbindsinksink1bindExpssubApplygraphDelayedAccgraphDelayedAfunFull PrettyGraphPNodePDocAvalAemptyApushdumpSimplStats dumpGraphdebuggingIsEnabledmonitoringIsEnabled UsesOfAcc ShrinkAccShrinkshrinkshrink' shrinkPreAccbasicReduceAcc usesOfExp usesOfPreAccrecoverAccSharingrecoverExpSharingrecoverSeqSharing floatOutAcc convertAcc convertAfunconvertOpenAccconvertSharingAccconvertSharingBoundary convertFun convertExpconvertSharingExpconvertSharingTupleconvertSharingFun1convertSharingFun2convertSharingStencilFun1convertSharingStencilFun2recoverSharingAccStableSharingAcc FunctionR Afunction AfunctionR NodeCount AccNodeCount ExpNodeCountNodeNameStableSharingExpRootExp ScopedExp UnscopedExp SharingExp VarSharing LetSharing ExpSharing ScopedAcc UnscopedAcc SharingAcc AvarSharing AletSharing AccSharingStableNameHeight StableASTNameconvertaconvertLayout EmptyLayout PushLayoutConfignewinsertcleanupNRSNursery StableArrayfreemalloc freeStableinsertUnmanagedcleanpurgereclaimmakeStableArraymakeWeakArrayData MemoryTable RemoteArrayTask completed withRemoteUsedStatusCleanDirty UnmanagedEvictedwideaccDim preAccDimexpDimAccDim delayedDim evalPrimAppSimplifyStats_terms_types_binders_vars_ops&+~+++EmbedAcc CunctationDoneYieldStepEmbedfloatOutAccFromExpenableAccFusionconvertOffsetOfSegmentphasesPhaseconvertAccWithconvertAfunWithAccType arrayTypeaccType preAccTypeexpType preExpTypesizeOfdelayedAccTypedelayedExpType mkHeadFlags mkTailFlags segmentedindex1'gatherIf scatterIf ApplicativeAtomicadd