*      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      BWhen converting a data type to its generic representation, we use  ; to help us convert only one layer at a time. For example:    data Foo a = Foo Int a  "instance PA a => PA (Foo a) where M type PRepr (Foo a) = (Int, Wrap a) -- define how (Foo a) is represented Here we've converted the Foo% data constructor to a pair, and Int 0 is its own representation type. We have PData/PR instances for pairs and C Ints, so we can work with arrays of these types. However, we can't just 9 use (Int, a) as the representation of (Foo a) because a might  be user defined and we won' t have PData/PR instances for it. KInstead, we wrap the second element with the Wrap constructor, which tells J us that if we want to process this element we still need to convert it G to the generic representation (and back). This last part is done by  the PR instance of Wrap, who'+s methods are defined by calls to the *PD  functions from  Data.Array.Parallel.PArray.PRepr. ASum types used for the generic representation of algebraic data.  !The !/ type is used when representing enumerations. & A type like Bool is represented as Sum2 Void Void, meaning that we only J only care about the tag of the data constructor and not its argumnent. "A value/ with the void type. Used as a placholder like #.  Forcing this yields $. % Coerce a !1 to a different type. Used as a placeholder like #.  Forcing the result yields $.  !"%   !"% &Force an array to normal form. 'Convert a list to an array. (LCopy an array, but update the values of some of the elements in the result. )'Combine two arrays based on a selector J The selector says which source array to choose for each element of the  resulting array. *MSelect some elements from an array that correspond to a particular tag value ! and pack them into a new array. #packByTag [:23, 42, 95, 50, 27, 49:] 3 [:1, 2, 1, 2, 3, 2:] 2 = [:42, 50, 49:] +Segmented append. ,Append two arrays. -AConstruct a new array by selecting elements from a source array. bpermute [:50, 60, 20, 30:] 3 [:0, 3, 2:] = [:50, 30, 20:] ..Extract a subrange of elements from an array. extract [:23, 42, 93, 50, 27:] 1 3 = [:42, 93, 50:] /+Retrieve a numbered element from an array. 08Produce an array containing copies of some other array. 1Segmented replicate. 27Produce an array containing copies of a given element. 3An empty array. GA PR dictionary contains the primitive functions that operate directly  on parallel array data. It'Bs called PR because the functions work on our internal, efficient + Representation of the user-level array.  !Parallel Data. ? This is the family of types that store parallel array data. IPData takes the type of an element and produces the type we use to store H an array of those elements. The instances for PData use an efficient E representation that depends on the type of elements being stored. L For example, an array of pairs is stored as two separate arrays, one for F each element type. This lets us avoid storing the intermediate Pair/Tuple 2 constructors and the pointers to the elements. %Most of the instances are defined in $Data.Array.Parallel.PArray.Instances, P though the instances for function closures are defined in their own module,  "Data.Array.Parallel.Lifted.Closure. MNote that PData is just a flat chunk of memory containing elements, and doesn't Q include a field giving the length of the array. We use PArray when we want to 5 pass around the array data along with its length. &'()*+,-./0123 !&'()*+,-./0123  ! "@A PA dictionary contains the functions that we use to convert a > representable type to and from its generic representation. . The conversion methods should all be O(1). #$%&'Representable types. ?The family of types that we know how to represent generically. J PRepr takes an arbitrary type and produces the generic type we use to  represent it. PInstances for simple types are defined in Data.Array.Parallel.Lifted.Instances.  For algebraic types, it's up to the vectoriser/client module to create  a suitable instance. ()*+,-./012345"#$%&'()*+,-./012345"#$%&#$%&'()*+,-./012345 6Class of scalar types. J Scalar types are the ones that we can store in our underlying U.Arrays 6 (which are currently implemented as Data.Vectors). GTo perform an operation on a PData array of scalar elements, we coerce L it to the underling U.Array and use the corresponding U.Array operators. 789:;<=>?@ABCDEF6789:;<=>?@ABCDEF678789:;<=>?@ABCDEF U456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~U456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~U456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~GLifted/bulk parallel arrays @ This contains the array length, along with the element data. HI#Take the length field of a PArray. J!Take the data field of a PArray. KLMNOPQRSTUVWXYGHIJKLMNOPQRSTUVWXYGHHIJKLMNOPQRSTUVWXYH !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXY;! :O(1). Extract the segment descriptor from a nested array. GO(1). Concatenate a nested array. This is a constant time operation as 5 we can just discard the segment descriptor. GO(1). Create a nested array from an element count, segment descriptor,  and data elements. CO(1). Create a nested array by using the element count and segment = descriptor from another, but use new data elements. ! ! ZThe type of closures.  This bundles up: S 1) the vectorised version of the function that takes an explicit environment 3 2) the lifted version, that works on arrays. 7 the first parameter of this function is the 'lifting context' / that gives the length of the array. ) 3) the environment of the closure. IThe vectoriser closure-converts the source program so that all functions % types are expressed in this form. ?Apply a lifted function by wrapping up the provided array data  into some real HGs, and passing it those. lifted function to call. lifting context environments  arguments returned elements Construct a closure. 0vectorised function, with explicit environment. 2lifted function, taking an array of environments.  environment Construct a closure.  This is like the * function above, except that the provided G lifted version of the function can take raw array data, instead of  data wrapped up into a HG. 0vectorised function, with explicit environment. 2lifted function, taking an array of environments.  environment [!Apply a closure to its argument. Lifted closure construction \Lifted closure application Arity-1 closures. Arity-2 closures. Arity-3 closures. GHZ[\ Z[\]^]^]^*Create a PArray out of a scalar U.Array, + the first argument is the array length. -TODO: ditch this version, just use fromUArrPA' _)Create a PArray out of a scalar U.Array, 1 reading the length directly from the U.Array. `*Convert a PArray back to a plain U.Array. )Convert an U.Array of pairs to a PArray. a(Convert a U.Array of pairs to a PArray, 1 reading the length directly from the U.Array. b*Convert a U.Array of triples to a PArray. c*Convert a U.Array of triples to a PArray, 1 reading the length directly from the U.Array. O(1). Create a nested array. -total number of elements in the nested array segment descriptor array of data elements. dO(1). Create a nested array, 4 using the same length as the source array. segment descriptor array of data elements LApply a worker function to every element of an array, yielding a new array. &Zip two arrays, yielding a new array. (Zip three arrays, yielding a new array. Left fold over an array. JLeft fold over an array, using the first element to initialise the state. &Segmented fold of an array of arrays. O Each segment is folded individually, yielding an array of the fold results. FSegmented fold of an array of arrays, using the first element of each 4 segment to initialse the state for that segment. S Each segment is folded individually, yielding an array of all the fold results. @Left fold over an array, also passing the index of each element  to the parameter function. >Segmented fold over an array, also passing the index of each & element to the parameter function. _`abcd_`abcd;)Take the number of elements in an array. OProduce a new array by replicating a single element the given number of times. .Produce an array containing a single element. KApply a worker function to each element of an array, yielding a new array. When performing a map we & the function into an array, then use L lifted-application to apply each function to its corresponding argument. DNote that this is a virtual replicate only, meaning that we can use J the same vectorised and lifted worker functions, provided we replicate C the environment part of the closure. The instance for repliatePA# in ( PRepr class does exactly this, and it's defined in  "Data.Array.Parallel.Lifted.Closure. >Takes two arrays and returns an array of corresponding pairs. M If one array is short, excess elements of the longer array are discarded. HzipWith generalises zip by zipping with the function given as the first , argument, instead of a tupling function. :Transform an array into an array of the first components, * and an array of the second components.   ASelect the elements of an array that have their tag set as True.   packPA [12, 24, 42, 93] [True, False, False, True]  = [24, 42]    QCombine two arrays, using a tag array to tell us where to get each element from.  combine2 [1,2,3] [4,5,6] [T,F,F,T,T,F] = [1,4,5,2,3,6].TODO: should the selector be a boolean array? CExtract the elements from an array that match the given predicate. 1Retrieve the array element with the given index. 4Concatenate an array of arrays into a single array. Append two arrays. Produce a range of integers.  !-Tag each element of an array with its index. indexed [42, 93, 13] = [(0, 42), (1, 93), (2, 13)]"#$.Extract a subrange of elements from an array. F The first argument is the starting index, while the second is the  length of the slice. %&'RCopy the source array in the destination, using new values for the given indices. ()*)Backwards permutation of array elements. bpermute [50, 60, 20, 30] [0, 3, 2] = [50, 30, 20]+,!  !"$%'(*+!  !"$%'(*+efgh(O(1). An empty array, with no elements. i1O(1). Retrieve a numbered element from an array. j$O(1). Yield the length of an array. k=O(n). Produce an array containing copies of a given element. l4O(1). Produce an array containing a single element. mDO(1). Takes two arrays and returns an array of corresponding pairs. H If one array is short, excess elements of the longer array are  discarded. n@O(1). Transform an array into an array of the first components, 0 and an array of the second components. oASelect the elements of an array that have their tag set as True.   packPA [12, 24, 42, 93] [True, False, False, True]  = [24, 42] p4Concatenate an array of arrays into a single array. qAppend two arrays r3O(n). Tag each element of an array with its index. indexed [42, 93, 13] = [(0, 42), (1, 93), (2, 13)]s.Extract a subrange of elements from an array. F The first argument is the starting index, while the second is the  length of the slice. tRCopy the source array in the destination, using new values for the given indices. u/O(n). Backwards permutation of array elements. bpermute [50, 60, 20, 30] [0, 3, 2] = [50, 30, 20]vO(n). Generate a range of Ints. w Create a HG from a list. xCreate a list from a HG. y$Ensure an array is fully evaluated. -."G_efghijklmnopqrstuvwxyG"efgjhklimnopqrstuvwx_yefgfghijklmnopqrstuvwxyz{|O !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\z{|NGH!"#$%&IJLMNKOPQRSTUVWXY)*+(,-./012345' 678:;<9=>?@ABCDEFZ[\z{|z{| /012345671234512345}~ }~}~89:;.<=- - ,.>?   -    -    ,    678G]^_`abcd}~ }~]^G678`_abcd @  - 678G]^_`abcd}~         A !"#$%&'()*()+(),()-./()0()1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e fgghijklmnopqrstuvwxyz{|}~%'                                                                 ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M NOOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~dph-parData.Array.Parallel.PreludeData.Array.Parallel"Data.Array.Parallel.Prelude.Double!Data.Array.Parallel.Prelude.FloatData.Array.Parallel.Prelude.Int!Data.Array.Parallel.Prelude.Word8Data.Array.Parallel.LiftedData.Array.Parallel.PArray Data.Array.Parallel.PArray.Types Data.Array.Parallel.PArray.PData Data.Array.Parallel.PArray.PRepr!Data.Array.Parallel.PArray.Scalar"Data.Array.Parallel.Lifted.UnboxedData.Array.Parallel.PArray.Base!Data.Array.Parallel.Lifted.PArray"Data.Array.Parallel.Lifted.TH.Repr*Data.Array.Parallel.PArray.ScalarInstances)Data.Array.Parallel.PArray.PDataInstances)Data.Array.Parallel.PArray.PReprInstances"Data.Array.Parallel.Lifted.Closure!Data.Array.Parallel.Prelude.Tuple!Data.Array.Parallel.Lifted.Scalar&Data.Array.Parallel.Lifted.CombinatorsData.Array.Parallel.PArrData.Array.Parallel.VectDepend Data.Array.Parallel.Prelude.BoolbaseGHC.Base otherwise singletonPlengthP replicatePmapPfilterPzipP crossMapP!:emptyP+:+ghc-prim GHC.TypesBoolDoubleFloatIntGHC.WordWord8FalseTruePRemptyPR replicatePR replicatelPRrepeatPRindexPR extractPR bpermutePRappPRapplPR packByTagPR combine2PRupdatePR fromListPRnfPRPDataPAtoPRepr fromPRepr toArrPRepr fromArrPReprPRepremptyPD replicatePD replicatelPDrepeatPDindexPD extractPD bpermutePDappPDapplPD packByTagPD combine2PDupdatePD fromListPDnfPDScalarfromScalarPData toScalarPData emptyPRScalarreplicatePRScalarreplicatelPRScalarrepeatPRScalar indexPRScalarextractPRScalarbpermutePRScalar appPRScalar applPRScalarpackByTagPRScalarcombine2PRScalarupdatePRScalarfromListPRScalar nfPRScalarPArray lengthPA#dataPA#emptyPA replicatePA# replicatelPA# repeatPA#indexPA# extractPA# bpermutePA#appPA#applPA# packByTagPA# combine2PA# updatePA# fromListPA# fromListPAnfPA:->$:$:^tup2tup3 fromUArrPA'toUArrPA fromUArrPA_2' fromUArrPA_3 fromUArrPA_3' nestUSegdPA'RandomrandomsrandomRsemptylength replicate singletonzipunzippackconcatindexedsliceupdatebpermute enumFromTofromListtoListnf fromPArrayPA toPArrayPAfromNestedPArrayPA&&and_l||or_lnotnot_landPorP==/=<=<>=>minmaxminimumPmaximumP minIndexP maxIndexP+-*negateabssumPproductPdivmodsqrt enumFromToPtoIntfromInt/recippiexplogsintancosasinatanacossinhtanhcoshasinhatanhacosh**logBasetruncateroundceilingfloorconcatPunzipPzipWithPcombinePupdateP bpermutePindexedPsliceP fromPArrayP toPArrayPfromNestedPArrayPWrapunWrapSum3Alt3_3Alt3_2Alt3_1Sum2Alt2_2Alt2_1VoidvoidGHC.Err undefinederrorfromVoidT_nfPR T_fromListPR T_updatePR T_combine2PR T_packByTagPRT_applPRT_appPR T_bpermutePR T_extractPR T_indexPR T_repeatPRT_replicatelPR T_replicatePR T_emptyPR PArray_Bool#PArray_Double# PArray_Word8# PArray_Int#Sel2Segd elementsSegd#mkSegd#replicateSel2# pickSel2#tagsSel2elementsSel2_0#elementsSel2_1# lengthPA_Int# emptyPA_Int#replicatePA_Int#replicatelPA_Int# repeatPA_Int# indexPA_Int#extractPA_Int#bpermutePA_Int# appPA_Int# applPA_Int# pack'PA_Int# packPA_Int#combine2'PA_Int#combine2PA_Int#fromListPA_Int# upToPA_Int#enumFromToPA_Int#enumFromThenToPA_Int#enumFromStepLenPA_Int# selectPA_Int#selectorToIndices2PA# sumPA_Int# sumPAs_Int#unsafe_mapPA_Int#unsafe_zipWithPA_Int#unsafe_foldPA_Int#unsafe_scanPA_Int#lengthPA_Word8#emptyPA_Word8#replicatePA_Word8#replicatelPA_Word8#repeatPA_Word8#indexPA_Word8#extractPA_Word8#bpermutePA_Word8# appPA_Word8# applPA_Word8#pack'PA_Word8# packPA_Word8#combine2'PA_Word8#combine2PA_Word8#fromListPA_Word8#unsafe_zipWithPA_Word8#unsafe_foldPA_Word8#unsafe_fold1PA_Word8#unsafe_foldPAs_Word8#lengthPA_Double#emptyPA_Double#replicatePA_Double#replicatelPA_Double#repeatPA_Double#indexPA_Double#extractPA_Double#bpermutePA_Double# appPA_Double#applPA_Double#pack'PA_Double#packPA_Double#combine2'PA_Double#combine2PA_Double#fromListPA_Double#unsafe_zipWithPA_Double#unsafe_foldPA_Double#unsafe_fold1PA_Double#unsafe_foldPAs_Double#lengthPA_Bool#replicatelPA_Bool# packPA_Bool# truesPA_Bool#truesPAs_Bool# fromBoolPA# toBoolPA#GenrecursiveCalls recursiveNamesplitjointypeNameArgOtherArgRecArgSplit CaseSplitPatSplitArgValNameGenValOtherValUnitValListValPDataVal ScalarVal tyBndrVarmkAppTsvarTsappTsvarEsappEs normalMatchvarPsvanillaC simpleFunDinlineDinstance_PDatanewtype_instance_PData splitConAppTy normaliseTysubstTy splitFunTy genPR_methods methodValsrecursiveMethodnameGensscalarInstancespdataScalarConinstance_PData_scalarinstance_Scalar_scalarinstance_PR_scalar scalarMethodvoidPRInstance voidMethodunitPRInstance unitMethodwrapPRInstancewrapGentupleInstances pdataTupConinstance_PData_tupinstance_PR_tuptupGenPWord8PDoublePFloatPIntpvoidpunitzipPA#unzipPA#zip3PA#segdPA# concatPA# segmentPA# copySegdPA#PUnitPWrapPNestedPSum2P_5P_4P_3P_2PBoolClolifted mkClosureclosure mkClosureP liftedClosure liftedApplyclosure1closure2closure3 prim_lengthPA fromUArrPA fromUArrPA_2 nestUSegdPA scalar_mapscalar_zipWithscalar_zipWith3 scalar_fold scalar_fold1 scalar_folds scalar_fold1sscalar_fold1Indexscalar_fold1sIndexlengthPA lengthPA_v lengthPA_l replicatePA replicatePA_v replicatePA_l singletonPA singletonPA_v singletonPA_lmapPAmapPA_vGHC.ListmapPA_l crossMapPA crossMapPA_v crossMapPA_lzipPAzipPA_vzipPA_l zipWithPA zipWithPA_v zipWithPA_lunzipPA unzipPA_v unzipPA_lpackPApackPA_vpackPA_lboolSel combine2PA combine2PA_v combine2PA_lfilterPA filterPA_v filterPA_lindexPA indexPA_v indexPA_lconcatPA concatPA_v concatPA_lappPAappPA_vappPA_lenumFromToPA_IntenumFromToPA_vdistanceenumFromToPA_l indexedPA indexedPA_v indexedPA_lslicePA slicePA_v slicePA_lupdatePA updatePA_v updatePA_l bpermutePA bpermutePA_v bpermutePA_l prim_randoms prim_randomRsMPArr emptyPArr replicatePArr singletonPArr indexPArr lengthPArrnewArraymkPArr minIndexPA maxIndexPA