{-# LANGUAGE BangPatterns #-}{-# LANGUAGE CPP #-}{-# LANGUAGE DeriveDataTypeable #-}{-# LANGUAGE FlexibleContexts #-}{-# LANGUAGE FlexibleInstances #-}{-# LANGUAGE GADTs #-}{-# LANGUAGE ScopedTypeVariables #-}{-# LANGUAGE StandaloneDeriving #-}{-# LANGUAGE TupleSections #-}{-# LANGUAGE TypeFamilies #-}{-# LANGUAGE TypeOperators #-}{-# OPTIONS_HADDOCK hide #-}-- |-- Module : Data.Array.Accelerate.Array.Sugar-- Copyright : [2008..2011] Manuel M T Chakravarty, Gabriele Keller, Sean Lee-- [2009..2013] Manuel M T Chakravarty, Gabriele Keller, Trevor L. McDonell-- [2013] Robert Clifton-Everest-- License : BSD3---- Maintainer : Manuel M T Chakravarty <chak@cse.unsw.edu.au>-- Stability : experimental-- Portability : non-portable (GHC extensions)--moduleData.Array.Accelerate.Array.Sugar(-- * Array representationArray(..),Scalar,Vector,Segments,Arrays(..),ArraysR(..),ArrRepr,ArrRepr',-- * Class of supported surface element types and their mapping to representation typesElt(..),EltRepr,EltRepr',-- * Derived functionsliftToElt,liftToElt2,sinkFromElt,sinkFromElt2,-- * Array shapesDIM0,DIM1,DIM2,DIM3,DIM4,DIM5,DIM6,DIM7,DIM8,DIM9,-- * Array indexing and slicingZ(..),(:.)(..),All(..),Any(..),Shape(..),Slice(..),-- * Array shape query, indexing, and conversionsshape,(!),newArray,allocateArray,fromIArray,toIArray,fromList,toList,-- * MiscellaneousshowShape,Foreign(..))where-- standard libraryimportData.TypeableimportData.Array.IArray(IArray)importqualifiedData.Array.IArrayasIArray-- friendsimportData.Array.Accelerate.TypeimportData.Array.Accelerate.Array.DataimportqualifiedData.Array.Accelerate.Array.RepresentationasRepr-- Surface types representing array indices and slices-- ------------------------------------------------------- Array indices are snoc type lists. That is, they're backwards ---- the end-of-list token, `Z`, occurs first. For example, the type of a-- rank-2 array index is @Z :. Int :. Int@.---- In Accelerate the rightmost dimension is the /fastest varying/ or innermost.-- |Rank-0 index--dataZ=Zderiving(Typeable,Show,Eq)-- |Increase an index rank by one dimension. The `:.` operator is-- used to construct both values and types.--infixl3:.datatail:.head=tail:.headderiving(Typeable,Show,Eq)-- | Marker for entire dimensions in slice descriptors.---- For example, when used in slices passed to `replicate`, the-- occurrences of `All` indicate the dimensions into which the array's-- existing extent will be placed, rather than the new dimensions-- introduced by replication.--dataAll=Allderiving(Typeable,Show,Eq)-- |Marker for arbitrary shapes in slice descriptors. Such arbitrary-- shapes may include an unknown number of dimensions.---- `Any` can be used in the leftmost position of a slice instead of-- `Z`, for example @(Any :. _ :. _)@. In the following definition-- `Any` is used to match against whatever shape the type variable-- `sh` takes:---- > repN :: (Shape sh, Elt e) => Int -> Acc (Array sh e) -> Acc (Array (sh:.Int) e)-- > repN n a = replicate (constant $ Any :. n) a--dataAnysh=Anyderiving(Typeable,Show,Eq)-- Representation change for array element types-- ----------------------------------------------- | Type representation mapping---- We represent tuples by using '()' and '(,)' as type-level nil and snoc to-- construct snoc-lists of types.--typefamilyEltRepra::*typeinstanceEltRepr()=()typeinstanceEltReprZ=()typeinstanceEltRepr(t:.h)=(EltReprt,EltRepr'h)typeinstanceEltReprAll=((),())typeinstanceEltRepr(AnyZ)=()typeinstanceEltRepr(Any(sh:.Int))=(EltRepr(Anysh),())typeinstanceEltReprInt=((),Int)typeinstanceEltReprInt8=((),Int8)typeinstanceEltReprInt16=((),Int16)typeinstanceEltReprInt32=((),Int32)typeinstanceEltReprInt64=((),Int64)typeinstanceEltReprWord=((),Word)typeinstanceEltReprWord8=((),Word8)typeinstanceEltReprWord16=((),Word16)typeinstanceEltReprWord32=((),Word32)typeinstanceEltReprWord64=((),Word64)typeinstanceEltReprCShort=((),CShort)typeinstanceEltReprCUShort=((),CUShort)typeinstanceEltReprCInt=((),CInt)typeinstanceEltReprCUInt=((),CUInt)typeinstanceEltReprCLong=((),CLong)typeinstanceEltReprCULong=((),CULong)typeinstanceEltReprCLLong=((),CLLong)typeinstanceEltReprCULLong=((),CULLong)typeinstanceEltReprFloat=((),Float)typeinstanceEltReprDouble=((),Double)typeinstanceEltReprCFloat=((),CFloat)typeinstanceEltReprCDouble=((),CDouble)typeinstanceEltReprBool=((),Bool)typeinstanceEltReprChar=((),Char)typeinstanceEltReprCChar=((),CChar)typeinstanceEltReprCSChar=((),CSChar)typeinstanceEltReprCUChar=((),CUChar)typeinstanceEltRepr(a,b)=(EltRepra,EltRepr'b)typeinstanceEltRepr(a,b,c)=(EltRepr(a,b),EltRepr'c)typeinstanceEltRepr(a,b,c,d)=(EltRepr(a,b,c),EltRepr'd)typeinstanceEltRepr(a,b,c,d,e)=(EltRepr(a,b,c,d),EltRepr'e)typeinstanceEltRepr(a,b,c,d,e,f)=(EltRepr(a,b,c,d,e),EltRepr'f)typeinstanceEltRepr(a,b,c,d,e,f,g)=(EltRepr(a,b,c,d,e,f),EltRepr'g)typeinstanceEltRepr(a,b,c,d,e,f,g,h)=(EltRepr(a,b,c,d,e,f,g),EltRepr'h)typeinstanceEltRepr(a,b,c,d,e,f,g,h,i)=(EltRepr(a,b,c,d,e,f,g,h),EltRepr'i)-- To avoid overly nested pairs, we use a flattened representation at the-- leaves.--typefamilyEltRepr'a::*typeinstanceEltRepr'()=()typeinstanceEltRepr'Z=()typeinstanceEltRepr'(t:.h)=(EltReprt,EltRepr'h)typeinstanceEltRepr'All=()typeinstanceEltRepr'(AnyZ)=()typeinstanceEltRepr'(Any(sh:.Int))=(EltRepr'(Anysh),())typeinstanceEltRepr'Int=InttypeinstanceEltRepr'Int8=Int8typeinstanceEltRepr'Int16=Int16typeinstanceEltRepr'Int32=Int32typeinstanceEltRepr'Int64=Int64typeinstanceEltRepr'Word=WordtypeinstanceEltRepr'Word8=Word8typeinstanceEltRepr'Word16=Word16typeinstanceEltRepr'Word32=Word32typeinstanceEltRepr'Word64=Word64typeinstanceEltRepr'CShort=CShorttypeinstanceEltRepr'CUShort=CUShorttypeinstanceEltRepr'CInt=CInttypeinstanceEltRepr'CUInt=CUInttypeinstanceEltRepr'CLong=CLongtypeinstanceEltRepr'CULong=CULongtypeinstanceEltRepr'CLLong=CLLongtypeinstanceEltRepr'CULLong=CULLongtypeinstanceEltRepr'Float=FloattypeinstanceEltRepr'Double=DoubletypeinstanceEltRepr'CFloat=CFloattypeinstanceEltRepr'CDouble=CDoubletypeinstanceEltRepr'Bool=BooltypeinstanceEltRepr'Char=ChartypeinstanceEltRepr'CChar=CChartypeinstanceEltRepr'CSChar=CSChartypeinstanceEltRepr'CUChar=CUChartypeinstanceEltRepr'(a,b)=(EltRepra,EltRepr'b)typeinstanceEltRepr'(a,b,c)=(EltRepr(a,b),EltRepr'c)typeinstanceEltRepr'(a,b,c,d)=(EltRepr(a,b,c),EltRepr'd)typeinstanceEltRepr'(a,b,c,d,e)=(EltRepr(a,b,c,d),EltRepr'e)typeinstanceEltRepr'(a,b,c,d,e,f)=(EltRepr(a,b,c,d,e),EltRepr'f)typeinstanceEltRepr'(a,b,c,d,e,f,g)=(EltRepr(a,b,c,d,e,f),EltRepr'g)typeinstanceEltRepr'(a,b,c,d,e,f,g,h)=(EltRepr(a,b,c,d,e,f,g),EltRepr'h)typeinstanceEltRepr'(a,b,c,d,e,f,g,h,i)=(EltRepr(a,b,c,d,e,f,g,h),EltRepr'i)-- Array elements (tuples of scalars)-- ------------------------------------ | Accelerate supports as array elements only simple atomic types, and tuples-- thereof. These element types are stored efficiently in memory, unpacked as-- consecutive elements without pointers.---- This class characterises the types of values that can be array elements, and-- hence, appear in scalar Accelerate expressions.--class(Showa,Typeablea,Typeable(EltRepra),Typeable(EltRepr'a),ArrayElt(EltRepra),ArrayElt(EltRepr'a))=>EltawhereeltType::{-dummy-}a->TupleType(EltRepra)fromElt::a->EltRepratoElt::EltRepra->aeltType'::{-dummy-}a->TupleType(EltRepr'a)fromElt'::a->EltRepr'atoElt'::EltRepr'a->ainstanceElt()whereeltType_=UnitTuplefromElt=idtoElt=ideltType'_=UnitTuplefromElt'=idtoElt'=idinstanceEltZwhereeltType_=UnitTuplefromEltZ=()toElt()=ZeltType'_=UnitTuplefromElt'Z=()toElt'()=Zinstance(Eltt,Elth)=>Elt(t:.h)whereeltType(_::(t:.h))=PairTuple(eltType(undefined::t))(eltType'(undefined::h))fromElt(t:.h)=(fromEltt,fromElt'h)toElt(t,h)=toEltt:.toElt'heltType'(_::(t:.h))=PairTuple(eltType(undefined::t))(eltType'(undefined::h))fromElt'(t:.h)=(fromEltt,fromElt'h)toElt'(t,h)=toEltt:.toElt'hinstanceEltAllwhereeltType_=PairTupleUnitTupleUnitTuplefromEltAll=((),())toElt((),())=AlleltType'_=UnitTuplefromElt'All=()toElt'()=AllinstanceElt(AnyZ)whereeltType_=UnitTuplefromElt_=()toElt_=AnyeltType'_=UnitTuplefromElt'_=()toElt'_=AnyinstanceShapesh=>Elt(Any(sh:.Int))whereeltType_=PairTuple(eltType(undefined::Anysh))UnitTuplefromElt_=(fromElt(undefined::Anysh),())toElt_=AnyeltType'_=PairTuple(eltType'(undefined::Anysh))UnitTuplefromElt'_=(fromElt'(undefined::Anysh),())toElt'_=AnyinstanceEltIntwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltInt8whereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltInt16whereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltInt32whereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltInt64whereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltWordwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltWord8whereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltWord16whereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltWord32whereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltWord64whereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltCShortwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltCUShortwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltCIntwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltCUIntwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltCLongwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltCULongwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltCLLongwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltCULLongwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltFloatwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltDoublewhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltCFloatwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltCDoublewhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltBoolwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltCharwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltCCharwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltCSCharwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstanceEltCUCharwhereeltType=singletonScalarTypefromEltv=((),v)toElt((),v)=veltType'_=SingleTuplescalarTypefromElt'=idtoElt'=idinstance(Elta,Eltb)=>Elt(a,b)whereeltType(_::(a,b))=PairTuple(eltType(undefined::a))(eltType'(undefined::b))fromElt(a,b)=(fromElta,fromElt'b)toElt(a,b)=(toElta,toElt'b)eltType'(_::(a,b))=PairTuple(eltType(undefined::a))(eltType'(undefined::b))fromElt'(a,b)=(fromElta,fromElt'b)toElt'(a,b)=(toElta,toElt'b)instance(Elta,Eltb,Eltc)=>Elt(a,b,c)whereeltType(_::(a,b,c))=PairTuple(eltType(undefined::(a,b)))(eltType'(undefined::c))fromElt(a,b,c)=(fromElt(a,b),fromElt'c)toElt(ab,c)=let(a,b)=toEltabin(a,b,toElt'c)eltType'(_::(a,b,c))=PairTuple(eltType(undefined::(a,b)))(eltType'(undefined::c))fromElt'(a,b,c)=(fromElt(a,b),fromElt'c)toElt'(ab,c)=let(a,b)=toEltabin(a,b,toElt'c)instance(Elta,Eltb,Eltc,Eltd)=>Elt(a,b,c,d)whereeltType(_::(a,b,c,d))=PairTuple(eltType(undefined::(a,b,c)))(eltType'(undefined::d))fromElt(a,b,c,d)=(fromElt(a,b,c),fromElt'd)toElt(abc,d)=let(a,b,c)=toEltabcin(a,b,c,toElt'd)eltType'(_::(a,b,c,d))=PairTuple(eltType(undefined::(a,b,c)))(eltType'(undefined::d))fromElt'(a,b,c,d)=(fromElt(a,b,c),fromElt'd)toElt'(abc,d)=let(a,b,c)=toEltabcin(a,b,c,toElt'd)instance(Elta,Eltb,Eltc,Eltd,Elte)=>Elt(a,b,c,d,e)whereeltType(_::(a,b,c,d,e))=PairTuple(eltType(undefined::(a,b,c,d)))(eltType'(undefined::e))fromElt(a,b,c,d,e)=(fromElt(a,b,c,d),fromElt'e)toElt(abcd,e)=let(a,b,c,d)=toEltabcdin(a,b,c,d,toElt'e)eltType'(_::(a,b,c,d,e))=PairTuple(eltType(undefined::(a,b,c,d)))(eltType'(undefined::e))fromElt'(a,b,c,d,e)=(fromElt(a,b,c,d),fromElt'e)toElt'(abcd,e)=let(a,b,c,d)=toEltabcdin(a,b,c,d,toElt'e)instance(Elta,Eltb,Eltc,Eltd,Elte,Eltf)=>Elt(a,b,c,d,e,f)whereeltType(_::(a,b,c,d,e,f))=PairTuple(eltType(undefined::(a,b,c,d,e)))(eltType'(undefined::f))fromElt(a,b,c,d,e,f)=(fromElt(a,b,c,d,e),fromElt'f)toElt(abcde,f)=let(a,b,c,d,e)=toEltabcdein(a,b,c,d,e,toElt'f)eltType'(_::(a,b,c,d,e,f))=PairTuple(eltType(undefined::(a,b,c,d,e)))(eltType'(undefined::f))fromElt'(a,b,c,d,e,f)=(fromElt(a,b,c,d,e),fromElt'f)toElt'(abcde,f)=let(a,b,c,d,e)=toEltabcdein(a,b,c,d,e,toElt'f)instance(Elta,Eltb,Eltc,Eltd,Elte,Eltf,Eltg)=>Elt(a,b,c,d,e,f,g)whereeltType(_::(a,b,c,d,e,f,g))=PairTuple(eltType(undefined::(a,b,c,d,e,f)))(eltType'(undefined::g))fromElt(a,b,c,d,e,f,g)=(fromElt(a,b,c,d,e,f),fromElt'g)toElt(abcdef,g)=let(a,b,c,d,e,f)=toEltabcdefin(a,b,c,d,e,f,toElt'g)eltType'(_::(a,b,c,d,e,f,g))=PairTuple(eltType(undefined::(a,b,c,d,e,f)))(eltType'(undefined::g))fromElt'(a,b,c,d,e,f,g)=(fromElt(a,b,c,d,e,f),fromElt'g)toElt'(abcdef,g)=let(a,b,c,d,e,f)=toEltabcdefin(a,b,c,d,e,f,toElt'g)instance(Elta,Eltb,Eltc,Eltd,Elte,Eltf,Eltg,Elth)=>Elt(a,b,c,d,e,f,g,h)whereeltType(_::(a,b,c,d,e,f,g,h))=PairTuple(eltType(undefined::(a,b,c,d,e,f,g)))(eltType'(undefined::h))fromElt(a,b,c,d,e,f,g,h)=(fromElt(a,b,c,d,e,f,g),fromElt'h)toElt(abcdefg,h)=let(a,b,c,d,e,f,g)=toEltabcdefgin(a,b,c,d,e,f,g,toElt'h)eltType'(_::(a,b,c,d,e,f,g,h))=PairTuple(eltType(undefined::(a,b,c,d,e,f,g)))(eltType'(undefined::h))fromElt'(a,b,c,d,e,f,g,h)=(fromElt(a,b,c,d,e,f,g),fromElt'h)toElt'(abcdefg,h)=let(a,b,c,d,e,f,g)=toEltabcdefgin(a,b,c,d,e,f,g,toElt'h)instance(Elta,Eltb,Eltc,Eltd,Elte,Eltf,Eltg,Elth,Elti)=>Elt(a,b,c,d,e,f,g,h,i)whereeltType(_::(a,b,c,d,e,f,g,h,i))=PairTuple(eltType(undefined::(a,b,c,d,e,f,g,h)))(eltType'(undefined::i))fromElt(a,b,c,d,e,f,g,h,i)=(fromElt(a,b,c,d,e,f,g,h),fromElt'i)toElt(abcdefgh,i)=let(a,b,c,d,e,f,g,h)=toEltabcdefghin(a,b,c,d,e,f,g,h,toElt'i)eltType'(_::(a,b,c,d,e,f,g,h,i))=PairTuple(eltType(undefined::(a,b,c,d,e,f,g,h)))(eltType'(undefined::i))fromElt'(a,b,c,d,e,f,g,h,i)=(fromElt(a,b,c,d,e,f,g,h),fromElt'i)toElt'(abcdefgh,i)=let(a,b,c,d,e,f,g,h)=toEltabcdefghin(a,b,c,d,e,f,g,h,toElt'i)-- |Convenience functions--singletonScalarType::IsScalara=>a->TupleType((),a)singletonScalarType_=PairTupleUnitTuple(SingleTuplescalarType)liftToElt::(Elta,Eltb)=>(EltRepra->EltReprb)->(a->b){-# INLINE liftToElt #-}liftToEltf=toElt.f.fromEltliftToElt2::(Elta,Eltb,Eltc)=>(EltRepra->EltReprb->EltReprc)->(a->b->c){-# INLINE liftToElt2 #-}liftToElt2f=\xy->toElt$f(fromEltx)(fromElty)sinkFromElt::(Elta,Eltb)=>(a->b)->(EltRepra->EltReprb){-# INLINE sinkFromElt #-}sinkFromEltf=fromElt.f.toEltsinkFromElt2::(Elta,Eltb,Eltc)=>(a->b->c)->(EltRepra->EltReprb->EltReprc){-# INLINE sinkFromElt2 #-}sinkFromElt2f=\xy->fromElt$f(toEltx)(toElty){-# RULES
"fromElt/toElt" forall e.
fromElt (toElt e) = e
#-}-- Foreign functions-- ------------------- Class for backends to choose their own representation of foreign functions.-- By default it has no instances. If a backend wishes to have an FFI it must-- provide an instance.--classTypeable2f=>Foreign(f::*->*->*)where-- Backends should be able to produce a string representation of the foreign-- function for pretty printing. It should contain the backend name and-- ideally a string uniquely identifying the foreign function being used.--strForeign::fargsresults->String-- Surface arrays-- ---------------- We represent tuples of arrays in the same way as tuples of scalars; using-- '()' and '(,)' as type-level nil and snoc. This characterises the domain of-- results of Accelerate array computations.--typefamilyArrRepra::*typeinstanceArrRepr()=()typeinstanceArrRepr(Arrayshe)=((),Arrayshe)typeinstanceArrRepr(b,a)=(ArrReprb,ArrRepr'a)typeinstanceArrRepr(c,b,a)=(ArrRepr(c,b),ArrRepr'a)typeinstanceArrRepr(d,c,b,a)=(ArrRepr(d,c,b),ArrRepr'a)typeinstanceArrRepr(e,d,c,b,a)=(ArrRepr(e,d,c,b),ArrRepr'a)typeinstanceArrRepr(f,e,d,c,b,a)=(ArrRepr(f,e,d,c,b),ArrRepr'a)typeinstanceArrRepr(g,f,e,d,c,b,a)=(ArrRepr(g,f,e,d,c,b),ArrRepr'a)typeinstanceArrRepr(h,g,f,e,d,c,b,a)=(ArrRepr(h,g,f,e,d,c,b),ArrRepr'a)typeinstanceArrRepr(i,h,g,f,e,d,c,b,a)=(ArrRepr(i,h,g,f,e,d,c,b),ArrRepr'a)typefamilyArrRepr'a::*typeinstanceArrRepr'()=()typeinstanceArrRepr'(Arrayshe)=ArrayshetypeinstanceArrRepr'(b,a)=(ArrReprb,ArrRepr'a)typeinstanceArrRepr'(c,b,a)=(ArrRepr(c,b),ArrRepr'a)typeinstanceArrRepr'(d,c,b,a)=(ArrRepr(d,c,b),ArrRepr'a)typeinstanceArrRepr'(e,d,c,b,a)=(ArrRepr(e,d,c,b),ArrRepr'a)typeinstanceArrRepr'(f,e,d,c,b,a)=(ArrRepr(f,e,d,c,b),ArrRepr'a)typeinstanceArrRepr'(g,f,e,d,c,b,a)=(ArrRepr(g,f,e,d,c,b),ArrRepr'a)typeinstanceArrRepr'(h,g,f,e,d,c,b,a)=(ArrRepr(h,g,f,e,d,c,b),ArrRepr'a)typeinstanceArrRepr'(i,h,g,f,e,d,c,b,a)=(ArrRepr(i,h,g,f,e,d,c,b),ArrRepr'a)-- Array type reification--dataArraysRarrswhereArraysRunit::ArraysR()ArraysRarray::(Shapesh,Elte)=>ArraysR(Arrayshe)ArraysRpair::ArraysRarrs1->ArraysRarrs2->ArraysR(arrs1,arrs2)class(Typeable(ArrRepra),Typeable(ArrRepr'a),Typeablea)=>Arraysawherearrays::a{- dummy -}->ArraysR(ArrRepra)arrays'::a{- dummy -}->ArraysR(ArrRepr'a)--toArr::ArrRepra->atoArr'::ArrRepr'a->afromArr::a->ArrReprafromArr'::a->ArrRepr'ainstanceArrays()wherearrays_=ArraysRunitarrays'_=ArraysRunit--toArr=idtoArr'=idfromArr=idfromArr'=idinstance(Shapesh,Elte)=>Arrays(Arrayshe)wherearrays_=ArraysRpairArraysRunitArraysRarrayarrays'_=ArraysRarray--toArr((),arr)=arrtoArr'=idfromArrarr=((),arr)fromArr'=idinstance(Arraysb,Arraysa)=>Arrays(b,a)wherearrays_=ArraysRpair(arrays(undefined::b))(arrays'(undefined::a))arrays'_=ArraysRpair(arrays(undefined::b))(arrays'(undefined::a))--toArr(b,a)=(toArrb,toArr'a)toArr'(b,a)=(toArrb,toArr'a)fromArr(b,a)=(fromArrb,fromArr'a)fromArr'(b,a)=(fromArrb,fromArr'a)instance(Arraysc,Arraysb,Arraysa)=>Arrays(c,b,a)wherearrays_=ArraysRpair(arrays(undefined::(c,b)))(arrays'(undefined::a))arrays'_=ArraysRpair(arrays(undefined::(c,b)))(arrays'(undefined::a))--toArr(cb,a)=let(c,b)=toArrcbin(c,b,toArr'a)toArr'(cb,a)=let(c,b)=toArrcbin(c,b,toArr'a)fromArr(c,b,a)=(fromArr(c,b),fromArr'a)fromArr'(c,b,a)=(fromArr(c,b),fromArr'a)instance(Arraysd,Arraysc,Arraysb,Arraysa)=>Arrays(d,c,b,a)wherearrays_=ArraysRpair(arrays(undefined::(d,c,b)))(arrays'(undefined::a))arrays'_=ArraysRpair(arrays(undefined::(d,c,b)))(arrays'(undefined::a))--toArr(dcb,a)=let(d,c,b)=toArrdcbin(d,c,b,toArr'a)toArr'(dcb,a)=let(d,c,b)=toArrdcbin(d,c,b,toArr'a)fromArr(d,c,b,a)=(fromArr(d,c,b),fromArr'a)fromArr'(d,c,b,a)=(fromArr(d,c,b),fromArr'a)instance(Arrayse,Arraysd,Arraysc,Arraysb,Arraysa)=>Arrays(e,d,c,b,a)wherearrays_=ArraysRpair(arrays(undefined::(e,d,c,b)))(arrays'(undefined::a))arrays'_=ArraysRpair(arrays(undefined::(e,d,c,b)))(arrays'(undefined::a))--toArr(edcb,a)=let(e,d,c,b)=toArredcbin(e,d,c,b,toArr'a)toArr'(edcb,a)=let(e,d,c,b)=toArredcbin(e,d,c,b,toArr'a)fromArr(e,d,c,b,a)=(fromArr(e,d,c,b),fromArr'a)fromArr'(e,d,c,b,a)=(fromArr(e,d,c,b),fromArr'a)instance(Arraysf,Arrayse,Arraysd,Arraysc,Arraysb,Arraysa)=>Arrays(f,e,d,c,b,a)wherearrays_=ArraysRpair(arrays(undefined::(f,e,d,c,b)))(arrays'(undefined::a))arrays'_=ArraysRpair(arrays(undefined::(f,e,d,c,b)))(arrays'(undefined::a))--toArr(fedcb,a)=let(f,e,d,c,b)=toArrfedcbin(f,e,d,c,b,toArr'a)toArr'(fedcb,a)=let(f,e,d,c,b)=toArrfedcbin(f,e,d,c,b,toArr'a)fromArr(f,e,d,c,b,a)=(fromArr(f,e,d,c,b),fromArr'a)fromArr'(f,e,d,c,b,a)=(fromArr(f,e,d,c,b),fromArr'a)instance(Arraysg,Arraysf,Arrayse,Arraysd,Arraysc,Arraysb,Arraysa)=>Arrays(g,f,e,d,c,b,a)wherearrays_=ArraysRpair(arrays(undefined::(g,f,e,d,c,b)))(arrays'(undefined::a))arrays'_=ArraysRpair(arrays(undefined::(g,f,e,d,c,b)))(arrays'(undefined::a))--toArr(gfedcb,a)=let(g,f,e,d,c,b)=toArrgfedcbin(g,f,e,d,c,b,toArr'a)toArr'(gfedcb,a)=let(g,f,e,d,c,b)=toArrgfedcbin(g,f,e,d,c,b,toArr'a)fromArr(g,f,e,d,c,b,a)=(fromArr(g,f,e,d,c,b),fromArr'a)fromArr'(g,f,e,d,c,b,a)=(fromArr(g,f,e,d,c,b),fromArr'a)instance(Arraysh,Arraysg,Arraysf,Arrayse,Arraysd,Arraysc,Arraysb,Arraysa)=>Arrays(h,g,f,e,d,c,b,a)wherearrays_=ArraysRpair(arrays(undefined::(h,g,f,e,d,c,b)))(arrays'(undefined::a))arrays'_=ArraysRpair(arrays(undefined::(h,g,f,e,d,c,b)))(arrays'(undefined::a))--toArr(hgfedcb,a)=let(h,g,f,e,d,c,b)=toArrhgfedcbin(h,g,f,e,d,c,b,toArr'a)toArr'(hgfedcb,a)=let(h,g,f,e,d,c,b)=toArrhgfedcbin(h,g,f,e,d,c,b,toArr'a)fromArr(h,g,f,e,d,c,b,a)=(fromArr(h,g,f,e,d,c,b),fromArr'a)fromArr'(h,g,f,e,d,c,b,a)=(fromArr(h,g,f,e,d,c,b),fromArr'a)instance(Arraysi,Arraysh,Arraysg,Arraysf,Arrayse,Arraysd,Arraysc,Arraysb,Arraysa)=>Arrays(i,h,g,f,e,d,c,b,a)wherearrays_=ArraysRpair(arrays(undefined::(i,h,g,f,e,d,c,b)))(arrays'(undefined::a))arrays'_=ArraysRpair(arrays(undefined::(i,h,g,f,e,d,c,b)))(arrays'(undefined::a))--toArr(ihgfedcb,a)=let(i,h,g,f,e,d,c,b)=toArrihgfedcbin(i,h,g,f,e,d,c,b,toArr'a)toArr'(ihgfedcb,a)=let(i,h,g,f,e,d,c,b)=toArrihgfedcbin(i,h,g,f,e,d,c,b,toArr'a)fromArr(i,h,g,f,e,d,c,b,a)=(fromArr(i,h,g,f,e,d,c,b),fromArr'a)fromArr'(i,h,g,f,e,d,c,b,a)=(fromArr(i,h,g,f,e,d,c,b),fromArr'a)-- |Multi-dimensional arrays for array processing.---- If device and host memory are separate, arrays will be transferred to the-- device when necessary (if possible asynchronously and in parallel with other-- tasks) and cached on the device if sufficient memory is available.--dataArrayshewhereArray::(Shapesh,Elte)=>EltReprsh-- extent of dimensions = shape->ArrayData(EltRepre)-- array payload->ArrayshederivinginstanceTypeable2Array-- |Scalars arrays hold a single element--typeScalare=ArrayDIM0e-- |Vectors are one-dimensional arrays--typeVectore=ArrayDIM1e-- |Segment descriptor (vector of segment lengths).---- To 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.--typeSegmentsi=Vectori-- Shorthand for common shape types--typeDIM0=ZtypeDIM1=DIM0:.InttypeDIM2=DIM1:.InttypeDIM3=DIM2:.InttypeDIM4=DIM3:.InttypeDIM5=DIM4:.InttypeDIM6=DIM5:.InttypeDIM7=DIM6:.InttypeDIM8=DIM7:.InttypeDIM9=DIM8:.Int-- Shape constraints and indexing-- -------------------------------- |Shapes and indices of multi-dimensional arrays--class(Eltsh,Elt(Anysh),Repr.Shape(EltReprsh))=>Shapeshwhere-- |Number of dimensions of a /shape/ or /index/ (>= 0).dim::sh->Int-- |Total number of elements in an array of the given /shape/.size::sh->Int-- |Magic value identifying elements ignored in 'permute'.ignore::sh-- |Yield the intersection of two shapesintersect::sh->sh->sh-- |Map 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).toIndex::sh->sh->Int-- |Inverse of 'toIndex'.fromIndex::sh->Int->sh-- |Apply a boundary condition to an index.bound::sh->sh->Boundarya->Eitherash-- |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.iter::sh->(sh->a)->(a->a->a)->a->a-- |Convert a minpoint-maxpoint index into a /shape/.rangeToShape::(sh,sh)->sh-- |Convert a /shape/ into a minpoint-maxpoint index.shapeToRange::sh->(sh,sh)-- |Convert a shape to a list of dimensions.shapeToList::sh->[Int]-- |Convert a list of dimensions into a shape.listToShape::[Int]->sh-- | The slice index for slice specifier 'Any sh'sliceAnyIndex::sh->Repr.SliceIndex(EltRepr(Anysh))(EltReprsh)()(EltReprsh)dim=Repr.dim.fromEltsize=Repr.size.fromElt-- (#) must be individually defined, as it holds for all instances *except*-- the one with the largest arityignore=toEltRepr.ignoreintersectsh1sh2=toElt(Repr.intersect(fromEltsh1)(fromEltsh2))fromIndexshix=toElt(Repr.fromIndex(fromEltsh)ix)toIndexshix=Repr.toIndex(fromEltsh)(fromEltix)boundshixbndy=caseRepr.bound(fromEltsh)(fromEltix)bndyofLeftv->LeftvRightix'->Right$toEltix'itershfcr=Repr.iter(fromEltsh)(f.toElt)crrangeToShape(low,high)=toElt(Repr.rangeToShape(fromEltlow,fromElthigh))shapeToRangeix=let(low,high)=Repr.shapeToRange(fromEltix)in(toEltlow,toElthigh)shapeToList=Repr.shapeToList.fromEltlistToShape=toElt.Repr.listToShapeinstanceShapeZwheresliceAnyIndex_=Repr.SliceNilinstanceShapesh=>Shape(sh:.Int)wheresliceAnyIndex_=Repr.SliceAll(sliceAnyIndex(undefined::sh))-- | Slices, aka generalised indices, as /n/-tuples and mappings of slice-- indices to slices, co-slices, and slice dimensions--class(Eltsl,Shape(SliceShapesl),Shape(CoSliceShapesl),Shape(FullShapesl))=>SliceslwheretypeSliceShapesl::*-- the projected slicetypeCoSliceShapesl::*-- the complement of the slicetypeFullShapesl::*-- the combined dimensionsliceIndex::sl{- dummy -}->Repr.SliceIndex(EltReprsl)(EltRepr(SliceShapesl))(EltRepr(CoSliceShapesl))(EltRepr(FullShapesl))instanceSliceZwheretypeSliceShapeZ=ZtypeCoSliceShapeZ=ZtypeFullShapeZ=ZsliceIndex_=Repr.SliceNilinstanceSlicesl=>Slice(sl:.All)wheretypeSliceShape(sl:.All)=SliceShapesl:.InttypeCoSliceShape(sl:.All)=CoSliceShapesltypeFullShape(sl:.All)=FullShapesl:.IntsliceIndex_=Repr.SliceAll(sliceIndex(undefined::sl))instanceSlicesl=>Slice(sl:.Int)wheretypeSliceShape(sl:.Int)=SliceShapesltypeCoSliceShape(sl:.Int)=CoSliceShapesl:.InttypeFullShape(sl:.Int)=FullShapesl:.IntsliceIndex_=Repr.SliceFixed(sliceIndex(undefined::sl))instanceShapesh=>Slice(Anysh)wheretypeSliceShape(Anysh)=shtypeCoSliceShape(Anysh)=ZtypeFullShape(Anysh)=shsliceIndex_=sliceAnyIndex(undefined::sh)-- Array operations-- ------------------ |Yield an array's shape--shape::Shapesh=>Arrayshe->shshape(Arraysh_)=toEltsh-- |Array indexing--infixl9!(!)::Arrayshe->sh->e{-# INLINE (!) #-}-- (Array sh adata) ! ix = toElt (adata `indexArrayData` index sh ix)-- FIXME: using this due to a bug in 6.10.x(!)(Arrayshadata)ix=toElt(adata`unsafeIndexArrayData`toIndex(toEltsh)ix)-- |Create an array from its representation function--newArray::(Shapesh,Elte)=>sh->(sh->e)->Arrayshe{-# INLINE newArray #-}newArrayshf=adata`seq`Array(fromEltsh)adatawhere(adata,_)=runArrayData$doarr<-newArrayData(sizesh)letwriteix=unsafeWriteArrayDataarr(toIndexshix)(fromElt(fix))itershwrite(>>)(return())return(arr,undefined)-- | Creates a new, uninitialized Accelerate array.--allocateArray::(Shapesh,Elte)=>sh->Arrayshe{-# INLINE allocateArray #-}allocateArraysh=adata`seq`Array(fromEltsh)adatawhere(adata,_)=runArrayData$(,undefined)`fmap`newArrayData(sizesh)-- | Convert an 'IArray' to an accelerated array.---- While the type signature mentions Accelerate internals that are not exported,-- in practice satisfying the type equality is straight forward. The index type-- @ix@ must be the unit type @()@ for singleton arrays, or an @Int@ or tuple of-- @Int@'s for multidimensional arrays.--fromIArray::(EltReprix~EltReprsh,IArrayae,IArray.Ixix,Shapesh,Eltix,Elte)=>aixe->ArrayshefromIArrayiarr=newArray(toEltsh)(\ix->iarrIArray.!toElt(fromEltix))where(lo,hi)=IArray.boundsiarrsh=Repr.rangeToShape(fromEltlo,fromElthi)-- | Convert an accelerated array to an 'IArray'.--toIArray::(EltReprix~EltReprsh,IArrayae,IArray.Ixix,Shapesh,Eltix,Elte)=>Arrayshe->aixetoIArrayarr=IArray.arraybnds[(ix,arr!toElt(fromEltix))|ix<-IArray.rangebnds]where(lo,hi)=Repr.shapeToRange(fromElt(shapearr))bnds=(toEltlo,toElthi)-- | Convert a list, with elements in row-major order, into an accelerated array.--fromList::(Shapesh,Elte)=>sh->[e]->Arrayshe{-# INLINE fromList #-}fromListshxs=adata`seq`Array(fromEltsh)adatawhere-- Assume the array is in dense row-major order. This is safe because-- otherwise backends would not be able to directly memcpy.--!n=sizesh(adata,_)=runArrayData$doarr<-newArrayDatanletgo!i_|i>=n=return()go!i(v:vs)=unsafeWriteArrayDataarri(fromEltv)>>go(i+1)vsgo_[]=error"Data.Array.Accelerate.fromList: not enough input data"--go0xsreturn(arr,undefined)-- | Convert an accelerated array to a list in row-major order.--toList::forallshe.Arrayshe->[e]{-# INLINE toList #-}toList(Arrayshadata)=go0where-- Assume underling array is in row-major order. This is safe because-- otherwise backends would not be able to directly memcpy.--!n=Repr.sizeshgo!i|i>=n=[]|otherwise=toElt(adata`unsafeIndexArrayData`i):go(i+1)-- Convert an array to a string--instanceShow(Arrayshe)whereshowarr@(Arraysh_adata)="Array ("++showShape(toEltsh::sh)++") "++show(toListarr)-- | Nicely format a shape as a string--showShape::Shapesh=>sh->StringshowShape=foldr(\shstr->str++" :. "++showsh)"Z".shapeToList