M      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                 ! " # $ % & ' ( ) * + , - . / 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 TUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~         ! " # $ % & ' ( ) * + , -./0123456789:;<=>?@ABCDEFGHIJKLq B[2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)Safe MN H[2009..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneD)O2Spawn an asynchronous action in a separate thread.PLike O , but using Q internally.RLike O , but using S internally.TRBlock the calling thread until the computation completes, then return the result.UaTest whether the asynchronous computation has already completed. If so, return the result, else .V*Cancel a running asynchronous computation.WOPRTUVc[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)SafeST/X8Conditional execution of a monadic debugging expression.?This does nothing unless the program is compiled in debug mode.YThe opposite of X.?This does nothing unless the program is compiled in debug mode.$Z[\]^_`abcdefghijklmnopqrstXYuvwxyz{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)None3 |}~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)SafeJiShow a signed . 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  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.The  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.The  function outputs the trace message together with a time stamp from the IO monad. This sequences the output with respect to other IO actions.The  function behaves like p with the difference that the message is emitted to the eventlog, if eventlog profiling is enabled at runtime.BPrint a message prefixed with the current elapsed wall-clock time.The f function emits a message to the eventlog, if eventlog profiling is available and enabled at runtime. Compared to , 7 sequences the event with respect to other IO actions.H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)SafePtMExecute 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.H[2009..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None"#ZIssue an internal error message'$internalError :: String -> String -> aSThrow an error if the condition evaluates to False, otherwise evaluate the result.4$internalCheck :: String -> String -> Bool -> a -> aKThrow an error if the index is not in range, otherwise evaluate the result..$boundsCheck :: String -> Int -> Int -> a -> a<Print a warning message if the condition evaluates to False.6$internalWarning :: String -> String -> Bool -> a -> a [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&';<=FNSTVh9XGeneralised array index, which may index only in a subset of the dimensions of a shape.Slice representation7Class of slice representations (which are nested pairs)Index representation7Class of index representations (which are nested pairs)1Project the shape of a slice from the full shape.YEnumerate all slices within a given bound. The innermost dimension changes most rapidly.See  for an example..number of dimensions (>= 0); rank of the array-total number of elements in an array of this shape empty shape.`[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)NoneDNmjA 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"#[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None1ST    c[2008..2018] Manuel M T Chakravarty, Gabriele Keller [2009..2018] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimental'non-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: * Half * Float * Double * CFloat * CDouble Non-numeric types: * Bool * Char * CChar * CSChar * CUChar SIMD vector types: * V2 * V3 * V4 * V8 * V16None&'+-1;=FST; AConstraint that values of these two types have the same bit widthiAll scalar typesAll single value typesj Bounded typesk Numeric typeslNon-numeric typesmFloating typesnIntegral types+All scalar element types implement Eq & Ord'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.{  123456789:;<=hgf !" #$%&i'(j)k*l+m,n-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`a[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)None &'+;=>?FTѮbHConversion 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.cProduct reificationd(Type-safe projection indices for tuples.:NB: We index tuples by starting to count from the *right*! befghcijdkl H[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneD:mA mutable atomic integernEDecrement the atomic value by the given amount. Return the old value.oBBitwise AND the atomic with the given value. Return the old value.p?Increase the atomic by the given amount. Returns the old value.q"Set the atomic to the given value.rGet the current value.msnopqr!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"#tLaunch 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.uaInitialise 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.vqExecute the given action and assign the elapsed wall-clock time as active time for the given processing element.w_Record the given number of seconds as active processing time for the given processing element.x7Allocated the number of bytes in the local memory spacey6Copied data between the local and remote memory spacesz/Performed a major GC of the remote memory space{DPerformed an eviction of a remote array of the given number of bytes|}~tuvwxyz{"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 Lifetime_[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;<=FNSTV3Generalised array division, like above but use for splitting an array into many subarrays, as opposed to extracting a single subarray.o$Slices, aka generalised indices, as nQ-tuples and mappings of slice indices to slices, co-slices, and slice dimensionst.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 projected/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.#Matrices are two-dimensional arrays"Vectors are one-dimensional arrays#Scalar arrays hold a single element)Dense, regular, multi-dimensional arrays.The  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  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, } for one-dimensional s, |) 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 tQ is the fastest varying). The allowable array element types are members of the " 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  and ()@Nested tuples of all of these, currently up to 15-elements wide. Note that j 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  type.Tuple reification.Tuples of Arrays. Note that this carries the ! class constraint rather than " 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.) consists of nested tuples of individual cs, currently up to 15-elements wide. Accelerate computations can thereby return multiple results.The  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);Floating point numbers (half, single, and double precision)  ()Shapes formed from  and ()?Nested tuples of all of these, currently up to 15-elements wideAdding new instances for ~ 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.#Marker for arbitrary dimensions in %& and %' descriptors.< can be used in the leftmost position of a slice instead of E, indicating that any dimensionality is admissible in that position.See %& and %' for examples. Marker for entire dimensions in %& and %' descriptors.Occurrences of Z indicate the dimensions into which the array's existing extent will be placed unchanged.See %& and %' for examples..Increase an index rank by one dimension. The 7 operator is used to construct both values and types. Rank-0 indexConvenience functionsYield an array's shape@Change the shape of an array without altering its contents. The 4 of the source and result arrays must be identical.Array indexingVCreate an array from its representation function, applied at each index of the array.?Create an array using a monadic function applied at each index.DCreate a vector from the concatenation of the given list of vectors..Creates a new, uninitialized Accelerate array..Convert elements of a list into an Accelerate .*This will generate a new multidimensional y 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:.fromList (Z:.5:.10) (repeat 0) :: Matrix FloatMatrix (Z :. 5 :. 10)5 [ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,5 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,5 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,5 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,5 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]You can also make use of the OverloadedLists6 extension to produce one-dimensional vectors from a finite list.[0..9] :: Vector Int&Vector (Z :. 10) [0,1,2,3,4,5,6,7,8,9]Note that this requires first traversing the list to determine its length, and then traversing it a second time to collect the elements into the array, thus forcing the spine of the list to be manifest on the heap.Convert an accelerated  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 ] Orphansk  opqrstuvwxyz{|}~   !"#$%&'()*+,-./01339 19 (`[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>?FQTVZ23456789:;<=>?@){[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 AAccelerate 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.B,Pointers into this particular remote memory.CfAttempt to allocate the given number of bytes in the remote memory space. Returns Nothing on failure.DICopy the given number of elements from the host array into remote memory.EGCopy the given number of elements from remote memory to the host array.FCast a remote pointer.G3Returns the total remote memory available in bytes.H/Returns, in bytes, the available remote memory.I"The chunk allocation size (bytes).J/Matches array element types to primitive types. ABCDEFGHIJ*[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,KPrimitive scalar operationsLPrimitive constant valuesMParametrised 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).N0Vanilla expression without free scalar variablesO5Parametrised expression without free scalar variablesPVanilla open expressionQ.Vanilla function without free scalar variablesR3Parametrised function without free scalar variablesS!Vanilla open function abstractionT&Parametrised open function abstractionUGADT reifying the V classVOperations on stencilsW7Boundary condition specification for stencil operationsX"Vanilla stencil boundary conditionYdCollective 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.Z,Closed array expression aka an array program[?Vanilla array-computation function without free array variables\DParametrised array-computation function without free array variables]9Function abstraction over parametrised array computations^_K`abcdefghijklmnopqrstuvwxyz{|}~LMNOPQRSTUVWXYZ[\]     +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 &'+;=FQSTVLOReplace 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;<=>?FSTV07Boundary condition specification for stencil operations-Scalar expressions to parametrise collective array operations, themselves parameterised over the type of collective array operations. The type R represents embedded scalar expressions. The collective operations of Accelerate ? consist of many scalar expressions executed in data-parallel.^Note that scalar expressions can not initiate new collective operations: doing so introduces nested data parallelismv, which is difficult to execute efficiently on constrained hardware such as GPUs, and is thus currently unsupported..=Array-valued collective computations without a recursive knotAccelerate is an embedded languageV that distinguishes between vanilla arrays (e.g. in Haskell memory on the CPU) and embedded arrays (e.g. in device memory on a GPU), as well as the computations on both of these. Since Accelerate is an embedded language, programs written in Accelerate are not compiled by the Haskell compiler (GHC). Rather, each Accelerate backend is a runtime compilerX which generates and executes parallel SIMD code of the target language at application runtime.The type constructor B represents embedded collective array operations. A term of type Acc aN is an Accelerate program which, once executed, will produce a value of type a (an  or a tuple of "). 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. A simple exampleBAs a simple example, to compute a vector dot product we can 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 (&s) of values, and produces a single (?) 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. Avoiding nested parallelism9As mentioned above, embedded scalar computations of type 1 can not initiate further collective operations.&Suppose we wanted to extend our above dotpE function to matrix-vector multiplication. First, let's rewrite our dotp function to take 4 arrays as input (which is typically what we want): qdotp :: Num a => Acc (Vector a) -> Acc (Vector a) -> Acc (Scalar a) dotp xs ys = fold (+) 0 ( zipWith (*) xs ys ){We might then be inclined to lift our dot-product program to the following (incorrect) matrix-vector product, by applying dotp" to each row of the input matrix: mvm_ndp :: Num a => Acc (Matrix a) -> Acc (Vector a) -> Acc (Vector a) mvm_ndp mat vec = let Z :. rows :. cols = unlift (shape mat) :: Z :. Exp Int :. Exp Int in generate (index1 rows) (\row -> the $ dotp vec (slice mat (lift (row :. All)))) Here, we use .M to create a one-dimensional vector by applying at each index a function to & out the corresponding row of the matrix to pass to the dotp function. However, since both . and &2 are data-parallel operations, and moreover that &  depends on the argument row given to it by the . function, this definition requires nested data-parallelism, and is thus not permitted. The clue that this definition is invalid is that in order to create a program which will be accepted by the type checker, we must use the function / to retrieve the result of the dotp) operation, effectively concealing that dotpK is a collective array computation in order to match the type expected by ., which is that of scalar expressions. Additionally, since we have fooled the type-checker, this problem will only be discovered at program runtime._In order to avoid this problem, we can make use of the fact that operations in Accelerate are rank polymorphic. The 0 operation reduces along the innermost dimension of an array of arbitrary rank, reducing the rank (dimensionality) of the array by one. Thus, we can ' the input vector to as many rowsj there are in the input matrix, and perform the dot-product of the vector with every row simultaneously:  mvm :: A.Num a => Acc (Matrix a) -> Acc (Vector a) -> Acc (Vector a) mvm mat vec = let Z :. rows :. cols = unlift (shape mat) :: Z :. Exp Int :. Exp Int vec' = A.replicate (lift (Z :. rows :. All)) vec in A.fold (+) 0 ( A.zipWith (*) mat vec' )-Note that the intermediate, replicated array vec' is never actually created in memory; it will be fused directly into the operation which consumes it. We discuss fusion next. FusionArray 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 1, . , and 2U. Each element of these operations can be computed independently of all others.Collective operations such as 0, 3, and 4|. 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: images/fusion_example_1.png images/fusion_example_2.pngYIf 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: images/fusion_example_3.png Here the element-wise sequence (# + . + 5L) will fuse into a single operation, which then fuses into the collective 0. operation. At this point in the program the 0/ must now be evaluated. In the final step the 1! reads in the array produced by 0%. As there is no fusion between the 0 and 1; steps, this program consists of two "loops"; one for the # + . + 5 + 0 step, and one for the final 1 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 6 and 7x, when applied to a real array, are executed in constant time, so in this situation these operations will not be fused. TipsSince  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. can be used anywhere a constant is expected, and indicates that the consumer of the value can receive an unspecified bit pattern.This is useful because a store of an undefined value can be assumed to not have any effect; we can assume that the value is overwritten with bits that happen to match what was already there. However, a store tox an undefined location could clobber arbitrary memory, therefore, its use in such a context would introduce undefined  behaviour.>There are (at least) two cases where you may want to use this: The %8 function requires an array of default values, into which the new values are combined. However, if you are sure the default values are not used, and will (eventually) be completely overwritten, then 9:King an array with this value will give you a new uninitialised array.;In the definition of sum data types. See for example  Data.Array.Accelerate.Data.Maybe and !Data.Array.Accelerate.Data.Either.012345678-9:;<=>?@ABCDEFGHIJKLMNOPQ.RSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~0000H[2009..2018] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None The function  allows you to convert a value between any two types whose underlying representations have the same bit size at each component. For example: ncoerce (x :: Exp Double) :: Exp Word64 coerce (x :: Exp (Int64,Float)) :: Exp (Complex Float, Word32)CFurthermore, as we typically declare newtype wrappers similarly to: /type instance EltRepr (Sum a) = ((), EltRepr a)This can be used instead of the newtype constructor, to go from the newtype's abstract type to the concrete type by dropping the extra ()* from the representation, and vice-versa.]You will get a runtime error if it fails to find a coercion between the two representations.;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 ;<=>?FST) 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. [2018] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None*The H class is used for scalar types which can be mapped over. Instances of # should satisfy the following laws: 2fmap id == id fmap (f . g) == fmap f . fmap gSReplace all locations in the input with the same value. The default definition is  fmap . const<, but this may be overridden with a more efficient version.An infix synonym for ,The name of this operator is an allusion to <=-. Note the similarities between their types: } ($) :: (Exp a -> Exp b) -> Exp a -> Exp b (<$>) :: Functor f => (Exp a -> Exp b) -> Exp (f a) -> Exp (f b)Whereas <= is function application, ( is function application lifted over a .A flipped version of '(<$)'. value. discards or ignores the result of evaluation.444>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+;<=cBasic numeric classConversion from an .>An integer literal represents the application of the function # to the appropriate value of type K. We export this specialised version where the return type is fixed to an D term in order to improve type checking in Accelerate modules when RebindableSyntax is enabled.\]^_?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+;<=,Fractional numbers, supporting real divisionConversion from a .JA floating point literal representations the application of the function  to a value of type K. We export this specialised version where the return type is fixed to an D term in order to improve type checking in Accelerate modules when RebindableSyntax is enabled.VW@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+;<=̺<Trigonometric and hyperbolic functions and related functionsJKMLN>?@ABCDEFGHIOAH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None +;<=>?(Accelerate lacks an arbitrary-precision <B type, which the standard <C 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 typesDH[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 defines equality  and inequality $ for scalar Accelerate expressions.For convenience, we include  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 negation4432EH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None*;<=FTCThe $ class for totally ordered datatypes  !"4444FH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+;<=GH[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 S to any instance of Generalisation of R to any instance of Generalisation of P to any instance of  HH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+;<=S*Operations over sequentially ordered typesZ[IH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+;<=.Integral numbers, supporting integral divisionPQRSTU%[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 :.let vec = fromList (Z:.10) [0..] :: Vector Intvec&Vector (Z :. 10) [0,1,2,3,4,5,6,7,8,9]1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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].let vec' = use vec :: Acc (Vector Int).let mat' = use mat :: Acc (Matrix Int):let tup = use (vec, mat) :: Acc (Vector Int, Matrix 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 Intvec&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:;run $ replicate (constant (Z :. (4::Int) :. 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:7run $ replicate (lift (Z :. All :. (4::Int))) (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:Grun $ replicate (constant (Z :. (2::Int) :. All :. (3::Int))) (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 f can be used in the slice specification to match against some arbitrary dimension. For example, here / matches against whatever shape type variable sh takes.:{[ let 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)run $ rep0 10 x0Vector (Z :. 10) [42,42,42,42,42,42,42,42,42,42]run $ 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,  and  can be used together.:{k let rep1 :: (Shape sh, Elt e) => Exp Int -> Acc (Array (sh :. Int) e) -> Acc (Array (sh :. Int :. Int) e)5 rep1 n a = replicate (lift (Any :. n :. All)) a:}run $ rep1 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 (") of three floating point numbers:5run $ generate (index1 3) (\_ -> 1.2) :: Vector FloatVector (Z :. 3) [1.2,1.2,1.2]Or equivalently:2run $ fill (constant (Z :. 3)) 1.2 :: Vector FloatVector (Z :. 3) [1.2,1.2,1.2]5The following will create a vector with the elements [1..10]:Arun $ generate (index1 10) (\ix -> unindex1 ix + 1) :: Vector Int'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 9/*, the program will fail with the error: p./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 (s) in their entirety. is the opposite of , and can be used to cut out@ entire dimensions. For example, for the two dimensional array mat:1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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]...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 ):7run $ slice (use mat) (constant (Z :. (2::Int) :. All))0Vector (Z :. 10) [20,21,22,23,24,25,26,27,28,29]!A fully specified index (with no 6s) returns a single element (zero dimensional array).6run $ slice (use mat) (constant (Z :. 4 :. 2 :: DIM2)) Scalar Z [42] The marker a can be used in the slice specification to match against some arbitrary (lower) dimension. Here ' matches whatever shape type variable sh takes::{ letX sl0 :: (Shape sh, Elt e) => Acc (Array (sh:.Int) e) -> Exp Int -> Acc (Array sh e)) sl0 a n = slice a (lift (Any :. n)):}.let vec = fromList (Z:.10) [0..] :: Vector Intrun $ sl0 (use vec) 4 Scalar Z [4]run $ sl0 (use mat) 4Vector (Z :. 5) [4,14,24,34,44] Of course,  and  can be used together.:{d let sl1 :: (Shape sh, Elt e) => Acc (Array (sh:.Int:.Int) e) -> Exp Int -> Acc (Array (sh:.Int) e)0 sl1 a n = slice a (lift (Any :. n :. All)):}run $ sl1 (use mat) 40Vector (Z :. 10) [40,41,42,43,44,45,46,47,48,49]8let cube = fromList (Z:.3:.4:.5) [0..] :: Array DIM3 IntcubeArray (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]run $ 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..] :: Vector Intxs&Vector (Z :. 10) [0,1,2,3,4,5,6,7,8,9]run $ 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..] :: Matrix IntxsMatrix (Z :. 3 :. 5) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]0let ys = fromList (Z:.5:.10) [1..] :: Matrix IntysMatrix (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]#run $ zipWith (+) (use xs) (use ys)Matrix (Z :. 3 :. 5) [ 1, 3, 5, 7, 9, 16, 18, 20, 22, 24, 31, 33, 35, 37, 39]CReduction of the innermost dimension of an array of arbitrary rank.+The shape of the result obeys the property: +shape (fold f z xs) == indexTail (shape xs)"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.1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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]run $ 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:{ let maximumSegmentSum2 :: forall sh e. (Shape sh, Num e, Ord e)& => Acc (Array (sh :. Int) e) -> Acc (Array sh e) maximumSegmentSumS = map (\v -> let (x,_,_,_) = unlift v :: (Exp e, Exp e, Exp e, Exp e) in x) . fold1 f . map g whereP f :: (Num a, Ord a) => Exp (a,a,a,a) -> Exp (a,a,a,a) -> Exp (a,a,a,a) f x y =2 let (mssx, misx, mcsx, tsx) = unlift x2 (mssy, misy, mcsy, tsy) = unlift y in6 lift ( mssx `max` (mssy `max` (mcsx+misy))( , misx `max` (tsx+misy)( , mcsy `max` (mcsx+tsy) , tsx+tsy ) --7 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):}Blet vec = fromList (Z:.10) [-2,1,-3,4,-1,2,1,-5,4,0] :: Vector Int!run $ maximumSegmentSum (use vec) Scalar Z [6] See also  JQ, which can be a useful way to compute multiple results from a single reduction. Variant of g that requires the innermost dimension of the array to be non-empty and doesn't need an default value.+The shape of the result obeys the property: +shape (fold f z xs) == indexTail (shape xs)"The first argument needs to be an  associative_ function to enable an efficient parallel implementation, but does not need to be commutative.%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).3let seg = fromList (Z:.4) [1,4,0,3] :: Segments IntsegVector (Z :. 4) [1,4,0,3]1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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]'run $ 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.0let vec = fromList (Z :. 10) [0..] :: Vector Intrun $ scanl (+) 10 (use vec)3Vector (Z :. 11) [10,10,11,13,16,20,25,31,38,46,55]5let mat = fromList (Z :. 4 :. 10) [0..] :: Matrix Intrun $ scanl (+) 0 (use mat)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 arr4let vec = fromList (Z:.10) [0..] :: Vector Int,let (res,sum) = run $ scanl' (+) 0 (use vec)res+Vector (Z :. 10) [0,0,1,3,6,10,15,21,28,36]sum Scalar Z [45]8let mat = fromList (Z:.4:.10) [0..] :: Matrix Int-let (res,sums) = run $ scanl' (+) 0 (use mat)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 innermost dimension of the array must not be empty. The first argument must be an  associative function.1let mat = fromList (Z:.4:.10) [0..] :: Matrix Intrun $ scanl1 (+) (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 index * 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)::{7 let histogram :: Acc (Vector Int) -> Acc (Vector Int) histogram xs =- let zeros = fill (constant (Z:.10)) 0- ones = fill (shape xs) 1 in6 permute (+) zeros (\ix -> index1 (xs!ix)) ones:}Slet xs = fromList (Z :. 20) [0,0,1,2,1,1,2,4,8,3,4,9,8,3,2,5,5,3,1,2] :: Vector Intrun $ 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::{4 let identity :: Num a => Exp Int -> Acc (Matrix a) identity n =' let zeros = fill (index2 n n) 0' ones = fill (index1 n) 1 inA permute const zeros (\(unindex1 -> i) -> index2 i i) ones:}run $ identity 5 :: Matrix IntMatrix (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.Regarding the defaults array:If you are sure that the default values are not necessary---they are not used by the combination function and every element will be overwritten---a default array created by 9:ing with the value K) will give you a new uninitialised array.: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 9L 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::{" let swap :: Exp DIM2 -> Exp DIM2 swap = lift1 f whereA f :: Z :. Exp Int :. Exp Int -> Z :. Exp Int :. Exp Int# f (Z:.y:.x) = Z :. x :. y:}1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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]let mat' = use mat/run $ 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 (Matrix a) -> Acc (Matrix 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 | +------------+Stencil boundary condition where coordinates beyond the array extent instead wrap around the array (circular boundary conditions).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.The function is passed the out-of-bounds index, so you can use it to specify different boundary conditions at each side. For example, the following would clamp out-of-bounds elements in the y-direction to zero, while having circular boundary conditions in the x-direction. ring :: Acc (Matrix Float) -> Acc (Matrix Float) ring xs = stencil f boundary xs where boundary :: Boundary (Matrix Float) boundary = function $ \(unlift -> Z :. y :. x) -> if y < 0 || y >= height then 0 else if x < 0 then xs ! index2 y (width+x) else xs ! index2 y (x-width) f :: Stencil3x3 Float -> Exp Float f = ... Z :. height :. width = unlift (shape xs)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 M 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.1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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]%runExp $ use mat ! constant (Z:.1:.2)12Extract the value from an array at the specified linear index. Multidimensional arrays in Accelerate are stored in row-major order with zero-based indexing.1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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]runExp $ use 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 even Determine 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: 2gcd 4 2 = 2 gcd (-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 index 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 valueM     19 9 88 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 %&'+<V6Return 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 unset!bit i is a value with the i$th bit set and all other bits clear." x `setBit` i is the same as  x .|. bit i#x `clearBit` i is the same as x .&. complement (bit i)$x `complementBit` i is the same as  x `xor` bit i%Return  if the nth bit of the argument is 1&Return " 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. !"#$%&'()*+,- !"#$%&'()*+,- 75688'8)8+8,8NH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+<>?NT)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.U$General coercion from integral typesTUOH[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;<=VaVSEfficient, machine-independent access to the components of a floating-point numberW4The radix of the representation (often 2) (constant)XThe number of digits of W in the significand (constant)Y@The lowest and highest values the exponent may assume (constant)ZAReturn the significand and an appropriately scaled exponent. If (m,n) = Z x then  x = m*b^^n, where b is the floating-point radix (W). Furthermore, either m and n are both zero, or  b^(d-1) <= ] m < b^d, where d = X x.[ Inverse of Z\'Corresponds to the second component of Z]&Corresponds to the first component of Z^AMultiply a floating point number by an integer power of the radix_6 if the argument is an IEEE "not-a-number" (NaN) value`9 if the argument is an IEEE infinity or negative-infinityaE if the argument is too small to be represented in normalized formatb) if the argument is an IEEE negative zeroc1 if the argument is an IEEE floating point numberdUA version of arctangent taking two real floating-point arguments. For real floating x and y, d y x[ computes the angle (from the positive x-axis) of the vector from the origin to the point (x,y). d y x returns a value in the range [-pi, pi].VWXYZ[\]^_`abcdPH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+;<=eevName the upper and lower limits of a type. Types which are not totally ordered may still have upper and lower bounds.XYe[2018] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%*+;<=>?FTV cb'&%*)( cb'&%*)([2016..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None +;<=>?FTV -,+0/. -,+0/.QH[2016..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None5[YX[ZONMLKJIHGFEDCBA@?>WVUTSRQP^_]\ !"TUVWXYZ[\]^_`abcdeRc[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 &';=QSTV-     SE[2010..2011] Ben Lever [2010..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None&'STVCalculate 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.TB[2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None&'QV M UH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None&'QSTV !"#$%&'()*+,-./VH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None"#&'+;=FQSTV1!"0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\WH[2015..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None"#%&';=NQVU]5Generate a dependency graph for the given computation^1Generate a dependency graph for an array function_`abc]^Xc[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 d?Display simplifier statistics. The counts are reset afterwards.eWrite a representation of the given input (a closed array expression or function) to file in Graphviz dot format in the temporary directory.OZ[\]^_`abcdefghijklmnopqrstXYuvwxyz{|}~|}~tuvwxyz{fghijdeYH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%&'QV- klmnopqrsZ[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;=FSTV]Jt'Recover sharing of array computations ?u'Recover sharing of scalar expressions ?v*Recover sharing of sequence computations ?w4Always float array computations out of expressions ?xbConvert a closed array expression to de Bruijn form while also incorporating sharing information.y\Convert a closed function over array computations, while incorporating sharing information.zaConvert 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 expressionConvert a unary functionsConvert a binary functions Convert a unary stencil function!Convert a binary stencil functionRecover sharing information and annotate the HOAS AST with variable and let binding annotations. The first argument determines whether array computations are floated out of expressions irrespective of whether they are shared or not   implies floating them out.Also returns the  s of all nM 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 n and P 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.)x'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 convertedxy}~[[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQSTVM \[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)None]VdCreate a fresh nursery.tWhen the nursery is garbage collected, the provided function will be run on each value to free the retained memory.*Look for an entry with the requested size.Add an entry to the nursery#Delete all entries from the nursery1The total number of bytes retained by the nursery][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%&'+DKQVu :An untyped reference to an array, similar to a StableName.5Create a new memory table from host to remote arrays.$The function supplied should be the  for the remote pointers being stored. This function will be called by the GC, which typically runs on a different thread. Unlike the  in A,, this function cannot depend on any state.ELook for the remote pointer corresponding to a given host-side array.jAllocate a new device array to be associated with the given host-side array. This may not always use the  provided by the A 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.Deallocate the device array associated with the given host-side array. Typically this should only be called in very specific circumstances.Deallocate the device array associated with the given StableArray. This is useful for other memory managers built on top of the memory table.Record an association between a host-side array and a remote memory area that was not allocated by accelerate. The remote memory will NOT be re-used once the host-side array is garbage collected.=This typically only has use for backends that provide an FFI.gInitiate garbage collection and mark any arrays that no longer have host-side equivalents as reusable.Call H on all arrays that are not currently associated with host-side arrays. Initiate garbage collection and G any remote arrays that no longer have matching host-side equivalents. Make a new .AMake a weak pointer using an array as a key. Unlike the standard /, this guarantees finalisers won't fire early. ^{[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 &'+QV];A Task represents a process executing asynchronously that can be polled for its status. This is necessary for backends that work asynchronously (i.e. the CUDA backend). If a backend is synchronous, the () instance can be used.(Returns true when the task has finished.5Create a new memory cache from host to remote arrays.$The function supplied should be the  for the remote pointers being stored. This function will be called by the GC, which typically runs on a different thread. Unlike the  in A,, 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.qThe 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 uses concurrency to interleave execution of different parts of the program), then w on the returned task should not return true until it is guaranteed there are no more accesses of the remote pointer.Allocate a new device array to be associated with the given host-side array. This has similar behaviour to malloc in Data.Array.Accelerate.Array.Memory.Table but also will copy remote arrays back to main memory in order to make space.The third argument indicates that the array should be considered frozen. That is to say 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? _{[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)NoneABCDEFGHIJ`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&';=V     _`abc]^ac[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 &'FQTVKDetermine 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 bc[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&'QVCReify 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 shapecH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%&'NQSTV]dH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None"#%&';<=QSTVS6ew[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%&'+.;<=QSTVApply 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 E& 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...9:;<=>?@ABCDEfH[2012..2017] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None"#;<= &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.<!" !"#$%&'()*9:;<=>?@ABCDEFGRST9n[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*+;<=>?FQSTV8m For use with -XRebindableSyntax, this class provides ( lifted to both scalar and array types. Pair each element with its index.let xs = fromList (Z:.5) [0..] :: Vector Floatrun $ 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)]2let mat = fromList (Z:.3:.4) [0..] :: Matrix Floatrun $ indexed (use mat)Matrix (Z :. 3 :. 4)Q [ (Z :. 0 :. 0,0.0), (Z :. 0 :. 1,1.0), (Z :. 0 :. 2,2.0), (Z :. 0 :. 3,3.0),Q (Z :. 1 :. 0,4.0), (Z :. 1 :. 1,5.0), (Z :. 1 :. 2,6.0), (Z :. 1 :. 3,7.0),Q (Z :. 2 :. 0,8.0), (Z :. 2 :. 1,9.0), (Z :. 2 :. 2,10.0), (Z :. 2 :. 3,11.0)];Apply a function to every element of an array and its index7Zip three arrays with the given function, analogous to .6Zip four arrays with the given function, analogous to .6Zip five arrays with the given function, analogous to .5Zip six arrays with the given function, analogous to .7Zip seven arrays with the given function, analogous to .7Zip eight arrays with the given function, analogous to .6Zip nine arrays with the given function, analogous to .@Zip two arrays with a function that also takes the element indexRZip 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 .ZZip eight arrays with the given function that also takes the element index, analogous to .YZip nine arrays with the given function that also takes the element index, analogous to .uCombine the elements of two arrays pairwise. The shape of the result is the intersection of the two argument shapes.0let m1 = fromList (Z:.5:.10) [0..] :: Matrix Int2let m2 = fromList (Z:.10:.5) [0..] :: Matrix Floatrun $ zip (use m1) (use m2)Matrix (Z :. 5 :. 5): [ (0,0.0), (1,1.0), (2,2.0), (3,3.0), (4,4.0),: (10,5.0), (11,6.0), (12,7.0), (13,8.0), (14,9.0),: (20,10.0), (21,11.0), (22,12.0), (23,13.0), (24,14.0),: (30,15.0), (31,16.0), (32,17.0), (33,18.0), (34,19.0),: (40,20.0), (41,21.0), (42,22.0), (43,23.0), (44,24.0)]CTake three arrays and return an array of triples, analogous to zip.ETake four arrays and return an array of quadruples, analogous to zip.FTake five arrays and return an array of five-tuples, analogous to zip.DTake six arrays and return an array of six-tuples, analogous to zip.HTake seven arrays and return an array of seven-tuples, analogous to zip.HTake seven arrays and return an array of seven-tuples, analogous to zip.HTake seven arrays and return an array of seven-tuples, analogous to zip.The converse of N, but the shape of the two results is identical to the shape of the argument.-If the argument array is manifest in memory,  is a no-op.?Take an array of triples and return three arrays, analogous to .ATake an array of quadruples and return four arrays, analogous to .?Take an array of 5-tuples and return five arrays, analogous to .>Take an array of 6-tuples and return six arrays, analogous to .@Take an array of 7-tuples and return seven arrays, analogous to .@Take an array of 8-tuples and return eight arrays, analogous to .@Take an array of 8-tuples and return eight arrays, analogous to .eReduction 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.0let vec = fromList (Z:.10) [0..] :: Vector Floatrun $ foldAll (+) 42 (use vec)Scalar Z [87.0]3let mat = fromList (Z:.5:.10) [0..] :: Matrix Floatrun $ foldAll (+) 0 (use mat)Scalar Z [1225.0] Variant of s that requires the reduced array to be non-empty and does not need a default value. The first argument must be an  associative function.HCheck 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] :: Matrix 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]run $ all even (use mat)(Vector (Z :. 4) [False,False,True,False]KCheck 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] :: Matrix 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]run $ any even (use mat)&Vector (Z :. 4) [True,True,True,False]8Check if all elements along the innermost dimension are .6Check if any element along the innermost dimension is .nCompute the sum of elements along the innermost dimension of the array. To find the sum of the entire array,  it first.0let mat = fromList (Z:.2:.5) [0..] :: Matrix Intrun $ sum (use mat)Vector (Z :. 2) [10,35]zCompute the product of the elements along the innermost dimension of the array. To find the product of the entire array,  it first.0let mat = fromList (Z:.2:.5) [0..] :: Matrix Intrun $ product (use mat)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 .Jlet mat = fromList (Z :. 3 :. 4) [1,4,3,8, 0,2,8,4, 7,9,8,8] :: Matrix IntmatMatrix (Z :. 3 :. 4) [ 1, 4, 3, 8, 0, 2, 8, 4, 7, 9, 8, 8]run $ 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 .Jlet mat = fromList (Z :. 3 :. 4) [1,4,3,8, 0,2,8,4, 7,9,8,8] :: Matrix IntmatMatrix (Z :. 3 :. 4) [ 1, 4, 3, 8, 0, 2, 8, 4, 7, 9, 8, 8]run $ 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 e0let vec = fromList (Z:.10) [1..10] :: Vector Intrun $ 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 f0let vec = fromList (Z:.10) [1..10] :: Vector Int run $ 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.3let seg = fromList (Z:.4) [1,4,0,3] :: Segments IntsegVector (Z :. 4) [1,4,0,3]1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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](run $ 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.3let seg = fromList (Z:.4) [1,4,0,3] :: Segments IntsegVector (Z :. 4) [1,4,0,3]1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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]:let (res,sums) = run $ 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 e 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 /= 03let seg = fromList (Z:.4) [1,4,0,3] :: Segments IntsegVector (Z :. 4) [1,4,0,3]1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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]'run $ 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.3let seg = fromList (Z:.4) [1,4,0,3] :: Segments IntsegVector (Z :. 4) [1,4,0,3]1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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](run $ 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 .3let seg = fromList (Z:.4) [1,4,0,3] :: Segments IntsegVector (Z :. 4) [1,4,0,3]1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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]:let (res,sums) = run $ 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 .3let seg = fromList (Z:.4) [1,4,0,3] :: Segments IntsegVector (Z :. 4) [1,4,0,3]1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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]'run $ 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./run $ fill (constant (Z:.10)) 0 :: Vector Float: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).5run $ enumFromN (constant (Z:.5:.10)) 0 :: Matrix 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).?run $ enumFromStepN (constant (Z:.5:.10)) 0 0.5 :: Matrix 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.0let m1 = fromList (Z:.5:.10) [0..] :: Matrix Intm1Matrix (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]0let m2 = fromList (Z:.10:.3) [0..] :: Matrix Intm2 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]run $ 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]1Generalised version of '(++)' where the argument 1 specifies which dimension to concatenate along.&Appropriate lenses are available from  3https://hackage.haskell.org/package/lens-acceleratelens-accelerate.0let m1 = fromList (Z:.5:.10) [0..] :: Matrix Intm1Matrix (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]0let m2 = fromList (Z:.10:.5) [0..] :: Matrix Intm2 Matrix (Z :. 10 :. 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]#run $ concatOn _1 (use m1) (use m2)Matrix (Z :. 5 :. 15)? [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4,? 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 5, 6, 7, 8, 9,? 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 10, 11, 12, 13, 14,? 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 15, 16, 17, 18, 19,? 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 20, 21, 22, 23, 24]#run $ concatOn _2 (use m1) (use m2)Matrix (Z :. 15 :. 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, 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 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]run $ 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] :: Matrix 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]run $ 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] :: Vector Int7let from = fromList (Z:.6) [1,3,7,2,5,3] :: Vector Int#run $ 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] :: Vector Float<let from = fromList (Z :. 6) [1,3,7,2,5,3] :: Vector Int<let mask = fromList (Z :. 6) [3,4,9,2,7,5] :: Vector IntDlet input = fromList (Z :. 9) [1,9,6,4,4,2,0,1,2] :: Vector FloatErun $ gatherIf (use from) (use mask) (> 4) (use defaults) (use input))Vector (Z :. 6) [6.0,6.0,1.0,6.0,2.0,4.0]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.9let to = fromList (Z :. 6) [1,3,7,2,5,8] :: Vector Int;let input = fromList (Z :. 7) [1,9,6,4,4,2,5] :: Vector Int>run $ scatter (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.9let to = fromList (Z :. 6) [1,3,7,2,5,8] :: Vector Int9let mask = fromList (Z :. 6) [3,4,9,2,7,5] :: Vector Int;let input = fromList (Z :. 7) [1,9,6,4,4,2,5] :: Vector IntQrun $ scatterIf (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.Generalised version of  where the argument ' specifies which dimension to reverse.&Appropriate lenses are available from  3https://hackage.haskell.org/package/lens-acceleratelens-accelerate.1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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]run $ reverseOn _1 (use mat)Matrix (Z :. 5 :. 10)+ [ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0,+ 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,+ 29, 28, 27, 26, 25, 24, 23, 22, 21, 20,+ 39, 38, 37, 36, 35, 34, 33, 32, 31, 30,+ 49, 48, 47, 46, 45, 44, 43, 42, 41, 40]run $ reverseOn _2 (use mat)Matrix (Z :. 5 :. 10)+ [ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]Generalised version of  where the argument -s specify which two dimensions to transpose.&Appropriate lenses are available from  3https://hackage.haskell.org/package/lens-acceleratelens-accelerate.1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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]!run $ transposeOn _1 _2 (use 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]7let box = fromList (Z:.2:.3:.5) [0..] :: Array DIM3 IntboxjArray (Z :. 2 :. 3 :. 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]!run $ transposeOn _1 _2 (use box)jArray (Z :. 2 :. 5 :. 3) [0,5,10,1,6,11,2,7,12,3,8,13,4,9,14,15,20,25,16,21,26,17,22,27,18,23,28,19,24,29]!run $ transposeOn _2 _3 (use box)jArray (Z :. 3 :. 2 :. 5) [0,1,2,3,4,15,16,17,18,19,5,6,7,8,9,20,21,22,23,24,10,11,12,13,14,25,26,27,28,29]!run $ transposeOn _1 _3 (use box)jArray (Z :. 5 :. 3 :. 2) [0,15,5,20,10,25,1,16,6,21,11,26,2,17,7,22,12,27,3,18,8,23,13,28,4,19,9,24,14,29]Yield the first nY elements in the innermost dimension of the array (plus all lower dimensional elements).1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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]run $ 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).1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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]run $ 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.1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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]run $ 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.1let mat = fromList (Z:.5:.10) [0..] :: Matrix 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]run $ 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 iGeneralised version of  where the argument , specifies which dimension to operate over.&Appropriate lenses are available from  3https://hackage.haskell.org/package/lens-acceleratelens-accelerate.Generalised version of  where the argument , specifies which dimension to operate over.&Appropriate lenses are available from  3https://hackage.haskell.org/package/lens-acceleratelens-accelerate.Generalised version of  where the argument , specifies which dimension to operate over.&Appropriate lenses are available from  3https://hackage.haskell.org/package/lens-acceleratelens-accelerate.Generalised version of  where the argument , specifies which dimension to operate over.&Appropriate lenses are available from  3https://hackage.haskell.org/package/lens-acceleratelens-accelerate.Generalised version of  where the argument , specifies which dimension to operate over.&Appropriate lenses are available from  3https://hackage.haskell.org/package/lens-acceleratelens-accelerate.Force 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 valuesstarting indexlengthstarting indexlength case subjectlist of cases to attempt default valuev500[2015..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%*+;<=>?FTV .The non-negative magnitude of a complex number,The phase of a complex number, in the range (-O, O]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 (-O, O]1; if the magnitude is zero, then so is the phase.CForm a complex number from polar components of magnitude and phase. t# is a complex value with magnitude 1 and phase t (modulo 2*O).(Return the real part of a complex number-Return the imaginary part of a complex number<Return the complex conjugate of a complex number, defined as conjugate(Z) = X - iY  $# $#g[2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None7;<=STzA class of things that support almost-equality, so that we can disregard small amounts of floating-point round-off error.mFails the test if the two arguments are not equal, allowing for a small amount of floating point inaccuracy.44[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.,Linear 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 t.@Change the shape of an array without altering its contents. The 4 of the source and result arrays must be identical.nXYZ[JKMLN>?@ABCDEFGHIOVWPQRSTU\]^_   !"123456789:;<=`adehgfijklmnopqrstuvwxyz{|}~     TUVWXYZ[\]^_`abcden~}|{zyxwvutopqrs !"[ZeYX_^]\UTSRQPWVOIHGFEDCBA@?>NLMKJVWXYZ[\]^_`abcdTU     `eda hgf  <=456789:;123ikjnmlh[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+<QSTVi[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None +<QSTVRj[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None %+<QSTVk[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQVl[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None"#+<STVW6mapping function to produce key array from input arraym[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None +<QSTVn[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None &'+<QSTVOo[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+<QSTV p[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+<QSTVK q[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None +<QSTV r[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+<QSTV+  s[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None +<QSTV t[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+<QSTVu[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQV G     v[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQV w[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+<QVx[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None +<QVwy[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQVz[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQV{[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+<QV7|[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+<QSTV}[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None%<QV~[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+<QV?[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQV!w[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None +<QSTV'!source indices to gather from mask vectorpredicate functiondefault values source values#destination indices to scatter into mask vectorpredicate functiondefault values source values[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQV)Y[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQV+[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQSTV-[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQV0 [2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQV2Q![2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQV4"[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQSTV6#[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQV9  !"#$[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+<QV;%[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+<QV>&[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None+<QV@Y'[2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQVB%&'([2009..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)NoneQVD3       !"#$%&'() [2016..2017] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None &'+;<=STWf' 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: Ssum = Fold (lift . Sum) (getSum . unlift) 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:  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: average = sum / lengthA more complex example: sumOfSquares = Fold (lift . Sum . (^2)) (getSum . unlift) 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. [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"#%&'<FQSTV^%FRun 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. %&'()*+, %&',+*()[2018] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None ;=>?FSTVn)-Lift a value into a  constructor.The  constructor/Returns  if the argument is 0Returns  if the argument is of the form Just _1The 1& function takes a default value and a  value. If the  is S, the default value is returned; otherwise, it returns the value contained in the .2The 2* function extracts the element out of the , constructor. If the argument was actually +, you will get an undefined value instead.3The 33 function takes a default value, a function, and a  value. If the n value is nothing, the default value is returned; otherwise, it applies the function to the value inside the  and returns the result4!Extract from an array all of the m values, together with a segment descriptor indicating how many elements along each dimension were returned. -./01234 -.30/124[2018] Trevor L. McDonellBSD3.Trevor L. McDonell <tmcdonell@cse.unsw.edu.au> experimentalnon-portable (GHC extensions)None ;=>?FSTVV =Lift a value into the  constructor>Lift a value into the  constructor?Return  if the argument is a -value@Return  if the argument is a -valueAThe A* function extracts the element out of the , constructor. If the argument was actually +, you will get an undefined value instead.BThe B* function extracts the element out of the , constructor. If the argument was actually +, you will get an undefined value instead.CThe C( function performs case analysis on the  type. If the value is  a, apply the first function to a ; if it is  b , apply the second function to b.DExtract from the array of  all of the p elements, together with a segment descriptor indicating how many elements along each dimension were returned.EExtract from the array of  all of the p elements, together with a segment descriptor indicating how many elements along each dimension were returned. =>?@ABCDE =>C?@ABDE+=       !!""##$%&'-(-)-*-+-,-K-;.;/;0;1;2;3;4;5;6;7;89:;<=>?@AB>C>D?E?F@GAHAIDJDKDLDMDNDOEPEQERESETEUEVEWGXGYGZG[G\G]G^G_G`HaIb%c%d%e%f%g%h%i%j%k%l%m%n%o%p%q%r%#%s%'%.%7%&%1%5%0%t%u%v%3%w%x%y%z%{%8%2%4%|%}%~%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                                                               NNOOOOOOOOOOOOOOOP     99999999 9!9"9#9$9%9&9'9(9)9*9+9,9-9.9/90919293949695969798999:9;9<9=9>9?9@9A9B9C9D9E9F9G9H9I9J9K9L9M9N9O9P9Q9R9S9T9:9U9V9W9X9Y9Z9[9\9L9]9^9_9`9a9b9c9d9e9f9g9h9M9i9j9k9l9m9n9o9p9q9r9s9t9u9v9w9x9y9z9/9{9|}~ J J                                  !"#$%&'()*+,&-.//00123344567899:;<=>?@ABCDEEFGHIJKLMNOPQRSTUUVVWWXXYYZZ[[\\]]^^__``aabcdefghijklmnnooppqqrrstuvwxyz{|}~   @    !!!!!!!!!!!!!!!!!!!"""""""*"""""""""""""""""""""""""""""""""""""""""""""""" " " " " """"""""""""""""""" "!"""#"$"%"&"'"(")"*"+","-"."/"0"1"23456789:;<=7>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\;<]^_`abcde(f(g(h(i(j(j(k(l(m(n(o(p(q(r(s)t)u)v)w)x)y)z){)|)}*~************(**)**+**************************************************************************V***8**********************************4*********J*** *(*7************ * * * * ******************** *!*"*#*$*%*&*'*(*)***+*,*-*.*/*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--PQR-S-T-------)-V---8--------------------U-*----V-J-- -(-7---------- - - - -------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-{-|-}-~-------------------------------------------------------------------------------------------------5-6BF%RRRRRRRRRRRRRRRRRRRRRR#SSSTTTTTTTTTTUUUUU U U U U UUUUVVVVVVVVVVVVVVV V!V"V#V$V%V&V'V(V)V*V+V,V-V.V/V0V1V2V3V4V5V6V7V8V9V:V;V<V=V>W?W@WAWBWCWDW=XEXFXGXHXIXJXKYLYMYNYOYPYQYRYSYTZUZVZWZXZYZZZ[Z\Z]Z^Z_Z`ZaZbZcZdZeZfZgZZhZiZj[k[l[m[n[o[p[q[r[s[t[u[v[w[x[y[z[{[|[}[~[[[[[[\\\\\\\\]]]]]]]]]]]]]^^^^^^^^^aaaaaaaaabbbbbcdddeeYeZe[fUfVfWfffffYfZf_f^ffff999999gggggghijkllmnoooooooooooopqrrstuvwxyz{|}~)accelerate-1.2.0.0-DwpJQS8DFdUAWKmXKOoa7kData.Array.Accelerate$Data.Array.Accelerate.Data.Semigroup!Data.Array.Accelerate.Data.Monoid Data.Array.Accelerate.Data.Maybe!Data.Array.Accelerate.Data.Either"Data.Array.Accelerate.Data.ComplexData.Array.Accelerate.Unsafe"Data.Array.Accelerate.Data.FunctorData.Array.Accelerate.Data.BitsData.Array.Accelerate.Data.Fold!Data.Array.Accelerate.Interpreter&Data.Array.Accelerate.Analysis.Hash.THData.Array.Accelerate.Async!Data.Array.Accelerate.Debug.Flags!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.LifetimeSystem.Mem.WeakfinalizeWeak"Data.Array.Accelerate.Array.Unique*Data.Array.Accelerate.Pretty.Graphviz.Type+Data.Array.Accelerate.Pretty.Graphviz.Monad'Data.Array.Accelerate.Test.NoFib.ConfigData.Array.Accelerate.TypeData.Array.Accelerate.Product Data.Atomic&Data.Array.Accelerate.Debug.Monitoring 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.Smartgeneratethefoldmap backpermutescanlstencilzipWithunzipreshapepermuteData.Array.Accelerate.PreludefillData.Array.Accelerate.LiftPrelude$!Data.Array.Accelerate.Classes.Num(Data.Array.Accelerate.Classes.Fractional&Data.Array.Accelerate.Classes.Floating(Data.Array.Accelerate.Classes.ToFloatingRational 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.IntegralFoldundef 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.Test.NoFib.Base*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.Type$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.Test.Similar.Data.Array.Accelerate.Test.NoFib.Spectral.SMVM3Data.Array.Accelerate.Test.NoFib.Spectral.RadixSort6Data.Array.Accelerate.Test.NoFib.Spectral.BlackScholes)Data.Array.Accelerate.Test.NoFib.Spectral(Data.Array.Accelerate.Test.NoFib.Sharing0Data.Array.Accelerate.Test.NoFib.Prelude.ZipWith0Data.Array.Accelerate.Test.NoFib.Prelude.Stencil-Data.Array.Accelerate.Test.NoFib.Prelude.Scan0Data.Array.Accelerate.Test.NoFib.Prelude.Permute,Data.Array.Accelerate.Test.NoFib.Prelude.Map-Data.Array.Accelerate.Test.NoFib.Prelude.Fold/Data.Array.Accelerate.Test.NoFib.Prelude.Filter4Data.Array.Accelerate.Test.NoFib.Prelude.Backpermute(Data.Array.Accelerate.Test.NoFib.Prelude/Data.Array.Accelerate.Test.NoFib.Issues.Issue930Data.Array.Accelerate.Test.NoFib.Issues.Issue4090Data.Array.Accelerate.Test.NoFib.Issues.Issue4070Data.Array.Accelerate.Test.NoFib.Issues.Issue3620Data.Array.Accelerate.Test.NoFib.Issues.Issue2880Data.Array.Accelerate.Test.NoFib.Issues.Issue2870Data.Array.Accelerate.Test.NoFib.Issues.Issue2640Data.Array.Accelerate.Test.NoFib.Issues.Issue2550Data.Array.Accelerate.Test.NoFib.Issues.Issue2280Data.Array.Accelerate.Test.NoFib.Issues.Issue1870Data.Array.Accelerate.Test.NoFib.Issues.Issue1850Data.Array.Accelerate.Test.NoFib.Issues.Issue1840Data.Array.Accelerate.Test.NoFib.Issues.Issue1680Data.Array.Accelerate.Test.NoFib.Issues.Issue1370Data.Array.Accelerate.Test.NoFib.Issues.Issue1230Data.Array.Accelerate.Test.NoFib.Issues.Issue1190Data.Array.Accelerate.Test.NoFib.Issues.Issue1140Data.Array.Accelerate.Test.NoFib.Issues.Issue102'Data.Array.Accelerate.Test.NoFib.Issues0Data.Array.Accelerate.Test.NoFib.Imaginary.SAXPY0Data.Array.Accelerate.Test.NoFib.Imaginary.SASUM/Data.Array.Accelerate.Test.NoFib.Imaginary.DotP*Data.Array.Accelerate.Test.NoFib.Imaginary Data.Array.Accelerate.Test.NoFibbaseGHC.BaseGHC.Num-negate<>memptymappendmconcat SemigroupMonoidghc-prim GHC.TypesBoolCharDoubleFloatIntGHC.IntInt8Int16Int32Int64MaybeOrderingWordGHC.WordWord8Word16Word32Word64 Data.EitherEitherFalseNothingJustTrueLeftRightLTEQGT Data.Complex:+ComplexData.SemigroupgetMinMingetMaxMaxData.Semigroup.InternalgetSumSum getProductProductForeign.C.TypesCCharCSCharCUCharCShortCUShortCIntCUIntCLongCULongCLLongCULLongCFloatCDouble GHC.FloatatanhacoshasinhtanhcoshsinhatanacosasintancossinlogBase**sqrtlogexppiGHC.RealdivModquotRemmoddivremquotrecip/GHC.EnummaxBoundminBoundpredsuccsignumabs*+.conststimessconcatGHC.Err undefinederror#half-0.2.2.3-HB7LP3HfmaoEQ4L06OFE9S Numeric.HalfgetHalfHalfIsScalar IsBoundedIsNumIsNonNum IsFloating IsIntegralSlice SliceShape CoSliceShape FullShape sliceIndexShapeDIM9DIM8DIM7DIM6DIM5DIM4DIM3DIM2DIM1DIM0SegmentsMatrixVectorScalarArrayArraysEltAnyAll:.Z fromFunction fromFunctionMfromListtoListStencilBoundaryExpAccconstantcoerceUnliftunliftLiftPlainliftlift1lift2lift3ilift1ilift2ilift3Functorfmap<$<$>$>void $fFunctorMax $fFunctorMin$fFunctorProduct $fFunctorSumNum fromInteger Fractional fromRationalFloating ToFloating toFloatingEq==/=&&||notOrd<><=>=minmaxcompareRealFracproperFractiontruncateroundceilingfloordiv'mod'divMod'EnumIntegral Stencil5x5x5 Stencil3x5x5 Stencil5x3x5 Stencil5x5x3 Stencil3x3x5 Stencil3x5x3 Stencil5x3x3 Stencil3x3x3 Stencil5x5 Stencil3x5 Stencil5x3 Stencil3x3Stencil9Stencil7Stencil5Stencil3unitfold1foldSegfold1Segscanl'scanl1scanrscanr'scanr1stencil2clampmirrorwrapfunction 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$fSemigroupExp$fSemigroupExp0$fSemigroupExp1$fSemigroupExp2$fSemigroupExp3 $fMonoidExp$fSemigroupExp4$fOrdMax$fEqMax$fNumExp $fBoundedExp$fUnliftExpMax $fLiftExpMax$fIsProductEltMax$fEltMax $fMonoidExp0$fSemigroupExp5$fOrdMin$fEqMin $fNumExp0 $fBoundedExp0$fUnliftExpMin $fLiftExpMin$fIsProductEltMin$fEltMin $fMonoidExp1 $fMonoidExp2 $fMonoidExp3 $fMonoidExp4 $fOrdProduct $fEqProduct$fUnliftExpProduct$fLiftExpProduct$fIsProductEltProduct $fEltProduct $fMonoidExp5$fOrdSum$fEqSum$fUnliftExpSum $fLiftExpSum$fIsProductEltSum$fEltSum IfThenElseEltT ifThenElseindexedimapzipWith3zipWith4zipWith5zipWith6zipWith7zipWith8zipWith9izipWith izipWith3 izipWith4 izipWith5 izipWith6 izipWith7 izipWith8 izipWith9zipzip3zip4zip5zip6zip7zip8zip9unzip3unzip4unzip5unzip6unzip7unzip8unzip9foldAllfold1Allallanyandorsumproductminimummaximumprescanl postscanlprescanr postscanrscanlSeg scanl'Seg scanl1Seg prescanlSeg postscanlSegscanrSeg scanr'Seg scanr1Seg prescanrSeg postscanrSegflatten enumFromN enumFromStepN++concatOnfiltergatherscatterreverse reverseOn transposeOntakedropinittailslitinitOntailOntakeOndropOnslitOn?|?caseofiteratesfoldlfstafstsndasndcurryuncurryindex0index1unindex1index2unindex2index3unindex3nulllength magnitudephasepolarmkPolarcisrealimag conjugate$fFunctorComplex$fFromIntegralaComplex $fFloatingExp$fFractionalExp $fEqComplex$fUnliftExpComplex$fLiftExpComplex$fIsProductcstComplex $fEltComplex $fEltComplex0 $fEltComplex1 $fEltComplex2 $fEltComplex3 indexArraylinearIndexArray arrayRank arrayShape arraySize arrayReshaperunFold$fFloatingFold$fFractionalFold $fNumFold$fApplicativeFold $fFunctorFoldrunrun1runN evalUndef evalCoerce evalPrimConstevalPrimevalPrjjustnothing isNothingisJust fromMaybefromJustmaybejusts$fLiftExpMaybe$fIsProductEltMaybe $fEltMaybe $fOrdMaybe $fEqMaybe$fFunctorMaybeleftrightisLeftisRightfromLeft fromRighteitherleftsrights$fLiftExpEither$fIsProductEltEither $fEltEither $fOrdEither $fEqEither$fFunctorEitherhashQ hashWithSaltQasyncasyncOn GHC.Conc.SyncforkOn asyncBoundControl.ConcurrentforkOSwaitpollcancelAsyncwhenunlessValueFlag dump_sched dump_execdump_asmdump_lddump_cc dump_gc_statsdump_gcdump_simpl_dotdump_dotdump_vectorisationdump_simpl_iterationsdump_simpl_stats dump_fusion dump_sharing dump_phasesverbosedebug force_recomp flush_cache fast_mathsimplifyfusion exp_sharing acc_sharingunfolding_use_thresholdsetValuegetValuegetFlagsetFlag clearFlagsetFlags clearFlagsinline ruleFired knownBranch betaReduce substitutionsimplifierDone fusionDoneresetSimplCount simplCountshowFFloatSIBasetracetraceIO traceEvent putTraceMsg traceEventIOtimedelapsed internalError internalCheck indexCheckinternalWarning boundsError unsafeError boundsCheck unsafeCheck boundsWarning unsafeWarning SliceIndex sliceShaperankemptySliceNilSliceAll SliceFixedunioniter shapeToListiter1 rangeToShape shapeToRange listToShapeLTFLifetime newLifetime withLifetime touchLifetime addFinalizermkWeakunsafeGetValue mkWeakPtr UniqueArraynewUniqueArraywithUniqueArrayPtrunsafeUniqueArrayPtrGHC.ForeignPtrunsafeForeignPtrToPtrtouchUniqueArray uniqueArrayIduniqueArrayDataEdgeVertexPortLabelNodeIdNode StatementGNEGraphTreeLeafForestppGraph ppSubgraph ppStatementppEdgeppVertexppNode ppNodeTreeppNodeIdDotStatedotNodesdotEdgesdotGraphfreshDot emptyStaterunDotevalDotexecDotmkLabelmkNodeIdmkGraph mkSubgraph TestConfigat Interpreter TestWord64 TestWord32 TestWord16 TestWord8 TestInt64 TestInt32 TestInt16TestInt8 TestDouble TestFloatTestHalfTestAllnofibIngredient BitSizeEqIsSingle ScalarType BoundedTypeNumType NonNumType FloatingType IntegralType byteSwap64 byteSwap32 byteSwap16V16V8V4V3V2BitSize TupleType TypeRunit TypeRscalar TypeRpair scalarType singleType boundedTypenumType nonNumType floatingType integralType VectorType Vector2Type Vector3Type Vector4Type Vector8Type Vector16Type SingleType NumSingleTypeNonNumSingleTypeSingleScalarTypeVectorScalarTypeIntegralBoundedTypeNonNumBoundedTypeIntegralNumTypeFloatingNumTypeTypeBoolTypeChar TypeCChar TypeCSChar TypeCUCharTypeHalf TypeFloat TypeDouble TypeCFloat TypeCDoubleTypeIntTypeInt8 TypeInt16 TypeInt32 TypeInt64TypeWord TypeWord8 TypeWord16 TypeWord32 TypeWord64 TypeCShort TypeCUShortTypeCInt TypeCUInt TypeCLong TypeCULong TypeCLLong TypeCULLong NonNumDict FloatingDict IntegralDict integralDict floatingDict nonNumDict IsProductProdRTupleIdxProdReprfromProdtoProdprod ProdRunit ProdRsnoc ZeroTupIdx SuccTupIdxAtomicaddwritereadbeginMonitoringinitAccMetrics withProcessoraddProcessorTimedidAllocateBytesLocaldidCopyBytesFromRemote didRemoteGC didEvictBytes ProcessorNativePTXdidAllocateBytesRemoteincreaseCurrentBytesRemotedecreaseCurrentBytesRemotedidCopyBytesToRemoteincreaseCurrentBytesNurserydecreaseCurrentBytesNurserysetCurrentBytesNurserygetCurrentBytesNursery ArrayEltRArrayEltMutableArrayData ArrayData runArrayDataregisterForeignPtrAllocator!mallocPlainForeignPtrBytesAlignedmallocForeignPtr HTYPE_INT HTYPE_WORD HTYPE_LONGHTYPE_UNSIGNED_LONG HTYPE_CCHAR ArrayPtrstouchArrayDataarrayEltunsafeIndexArrayDataptrsOfArrayData newArrayDataunsafeReadArrayDataunsafeWriteArrayDataunsafeFreezeArrayDataptrsOfMutableArrayData ArrayEltRunit ArrayEltRint ArrayEltRint8ArrayEltRint16ArrayEltRint32ArrayEltRint64 ArrayEltRwordArrayEltRword8ArrayEltRword16ArrayEltRword32ArrayEltRword64ArrayEltRcshortArrayEltRcushort ArrayEltRcintArrayEltRcuintArrayEltRclongArrayEltRculongArrayEltRcllongArrayEltRcullong ArrayEltRhalfArrayEltRfloatArrayEltRdoubleArrayEltRcfloatArrayEltRcdouble ArrayEltRbool ArrayEltRcharArrayEltRccharArrayEltRcscharArrayEltRcuchar ArrayEltRvec2 ArrayEltRvec3 ArrayEltRvec4 ArrayEltRvec8ArrayEltRvec16 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_HalfAD_Float AD_Double AD_CFloat AD_CDoubleAD_BoolAD_CharAD_CChar AD_CSChar AD_CUCharAD_V2AD_V3AD_V4AD_V8AD_V16AD_Pair fstArrayData sndArrayData pairArrayDataDivision sliceAnyIndexsliceNoneIndexTupleRAtupleTuple TupleReprEltReprDivideSplitsingletonScalarType concatVectors allocateArray showShape$fShow(,,,,,,,,,,,,,,,) DivisionSlice slicesIndexNilAtupSnocAtupNilTupSnocTuparraysflavourtoArrfromArr ArraysFlavour ArraysFunit ArraysFarray ArraysFtupleArraysR ArraysRunit ArraysRarray ArraysRpairIsAtupleArrReprForeign strForeign liftForeigntoElteltTypefromEltIsTuple 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 PrimMinBound PrimMaxBoundPrimPiUnionConstVarIndexLetPrjIndexNil IndexCons IndexHead IndexTailIndexAny IndexSlice IndexFullToIndex FromIndexCondWhilePrimApp LinearIndex ShapeSize IntersectUndefCoerceBodyLam StencilRunit3 StencilRunit5 StencilRunit7 StencilRunit9 StencilRtup3 StencilRtup5 StencilRtup7 StencilRtup9ConstantFunctionClampMirrorWrapPermuteUnitMapFold1ApplyZipWith BackpermuteAletAvarAprjAforeignAcondAwhileUseReshapeGenerate Transform ReplicateFoldSegFold1SegScanlScanl'Scanl1ScanrScanr'Scanr1Stencil2OpenAccOpenAfunAbodyAlamValEltEmptyEltPushEltValEmptyPushIdxZeroIdxSuccIdxidxToInt tupleIdxToIntprjprjEltrnfPreOpenAfun rnfPreOpenAcc rnfArrays rnfPreOpenFun rnfPreOpenExpliftIdx liftTupleIdxliftPreOpenAfunliftPreOpenAccliftPreOpenFunliftPreOpenExp liftArraysliftSliceIndex liftPrimConst liftPrimFun liftConst showPreAccOp showPreExpOp substitutecompose RebuildAcc:?>SinkExpweakenESinkweaken:> RebuildTupunRTupRebuildableAccRebuildableExprebuildErebuildPartialE RebuildableAccClorebuildPartialrebuildAsubTopsubAtop strengthen strengthenEconvertSegmentsconvertSegmentsAfunPreAccGHC.ShowShow StencilRepr stencilPrjTagPipeAtagLevelatup2atup3atup4atup5atup6atup7atup8atup9atup10atup11atup12atup13atup14atup15atup16unatup2unatup3unatup4unatup5unatup6unatup7unatup8unatup9unatup10unatup11unatup12unatup13unatup14unatup15unatup16tup2tup3tup4tup5tup6tup7tup8tup9tup10tup11tup12tup13tup14tup15tup16untup2untup3untup4untup5untup6untup7untup8untup9untup10untup11untup12untup13untup14untup15untup16 mkMinBound mkMaxBoundmkPimkSinmkCosmkTanmkAsinmkAcosmkAtanmkSinhmkCoshmkTanhmkAsinhmkAcoshmkAtanh mkExpFloatingmkSqrtmkLogmkFPow mkLogBasemkAddmkSubmkMulmkNegmkAbsmkSigmkQuotmkRem mkQuotRemmkIDivmkModmkDivModmkBAndmkBOrmkBXormkBNot mkBShiftL mkBShiftR mkBRotateL mkBRotateR mkPopCountmkCountLeadingZerosmkCountTrailingZerosmkFDivmkRecip mkTruncatemkRoundmkFloor mkCeilingmkAtan2mkIsNaN mkIsInfinitemkLtmkGtmkLtEqmkGtEqmkEqmkNEqmkMaxmkMinmkLAndmkLOrmkLNotmkOrdmkChrmkFromIntegral mkToFloating mkBoolToInt mkBitcastmkUnsafeCoerce$$$$$$$$$$$$$$ integer-gmpGHC.Integer.TypeIntegerReal PrettyEnv prettyEnv PrettyAcc prettyOpenAccprettyOpenAfun prettyOpenFun prettyOpenExpprettyPreOpenAccprettyPreOpenAfun prettyPreFunprettyPreOpenFun prettyPreExpprettyPreOpenExpprettyTupleIdx prettyPrim prettyArraysnoParenssizeEnvoffsets positionsRoffsets2 EncodeAccHashhashPreOpenAcchashPreOpenFunhashPreOpenExp encodeOpenAccencodePreOpenAcc encodeOpenExpencodePreOpenExpencodePreOpenFunData.Type.Equality:~:ReflMatchAccmatchPreOpenAccmatchPreOpenAfunmatchPreOpenExpmatchPreOpenFunmatchIdx matchPrimFun matchPrimFun'matchTupleTypematchScalarType matchNumTypematchIntegralTypematchFloatingType SupplementBaseSupPushSupExtendBaseEnvPushEnvGammaEmptyExpPushExpDelayedOpenAccDelayedManifestextentDindexD linearIndexDDelayedOpenFunDelayedOpenExpDelayedOpenAfun DelayedFun DelayedExp DelayedAfun DelayedAccMatchmatchKitextract prettyAcc encodeAccmatchAccinject fromOpenAccavarInkmap fromOpenAfunhashDelayedOpenAccencodeDelayedOpenAccmatchDelayedOpenAccincExpprjExppushExpappendbindsinksink1bindExpsgraphDelayedAccgraphDelayedAfunDetailSimpleFull PrettyGraphdumpSimplStats dumpGraphdebuggingIsEnabledmonitoringIsEnabledboundsChecksAreEnabledunsafeChecksAreEnabledinternalChecksAreEnabled UsesOfAcc ShrinkAccShrinkshrinkshrink' shrinkPreAccbasicReduceAcc usesOfExp usesOfPreAccrecoverAccSharingrecoverExpSharingrecoverSeqSharing floatOutAcc convertAcc convertAfunconvertOpenAccconvertSharingAccconvertSharingBoundary convertFun convertExpconvertSharingExpconvertSharingTupleconvertSharingFun1convertSharingFun2convertSharingStencilFun1convertSharingStencilFun2recoverSharingAccStableSharingAcc FunctionR Afunction AfunctionRRunNRundim0dim1dim2dim3arrayinti8i16i32i64wordw8w16w32w64f16f32f64 log_flt_maxflt_maxflt_minexcept splitEvery splitPlacesnewlookupinsertcleanupNurseryNRS StableArrayfreemalloc freeStableinsertUnmanagedcleanpurgereclaimmakeStableArraymakeWeakArrayData MemoryTableTask completed withRemoteAccType arrayTypeaccType preAccTypeexpType preExpTypesizeOfdelayedAccTypedelayedExpTypeaccDim preAccDimexpDimAccDim delayedDim evalPrimAppSimplify+++EmbedAccfloatOutAccFromExpenableAccFusionconvertOffsetOfSegmentphasesPhaseconvertAccWithconvertAfunWith mkHeadFlags mkTailFlags segmentedindex1'"lens-4.16.1-5GB6gRjbaA08Xx3HbfUla6Control.Lens.TypeLens'gatherIf scatterIfSimilar~~~~=Sim absRelTol test_smvmtest_radixsorttest_blackscholes test_spectralsortKey test_sharing test_zipWith test_stencil test_scanl test_scanl1 test_scanl' test_scanr test_scanr1 test_scanr' test_scanlSegtest_scanl1Segtest_scanl'Seg test_scanrSegtest_scanr1Segtest_scanr'Seg test_permutetest_map test_fold test_foldSeg test_filtertest_backpermute test_prelude test_issue93 test_issue409 test_issue407 test_issue362 test_issue288 test_issue287 test_issue264 test_issue255 test_issue228 test_issue187 test_issue185 test_issue184 test_issue168 test_issue137 test_issue123 test_issue119 test_issue114 test_issue102 test_issues test_saxpy test_sasum test_dotptest_imaginarynofib Applicative