accelerate-io 1.0.0.1 → 1.2.0.0
raw patch · 30 files changed
+2955/−998 lines, 30 filesdep +accelerate-iodep +hedgehogdep +primitivedep ~acceleratedep ~arraydep ~base
Dependencies added: accelerate-io, hedgehog, primitive, tasty, tasty-hedgehog
Dependency ranges changed: accelerate, array, base, vector
Files
- CHANGELOG.md +22/−4
- Data/Array/Accelerate/IO.hs +0/−47
- Data/Array/Accelerate/IO/BMP.hs +0/−62
- Data/Array/Accelerate/IO/BlockCopy.hs +0/−247
- Data/Array/Accelerate/IO/ByteString.hs +0/−49
- Data/Array/Accelerate/IO/IArray.hs +0/−97
- Data/Array/Accelerate/IO/Ptr.hs +0/−100
- Data/Array/Accelerate/IO/Repa.hs +0/−177
- Data/Array/Accelerate/IO/Vector.hs +0/−172
- accelerate-io.cabal +73/−43
- src/Data/Array/Accelerate/IO/Codec/BMP.hs +82/−0
- src/Data/Array/Accelerate/IO/Data/Array/IArray.hs +107/−0
- src/Data/Array/Accelerate/IO/Data/Array/Internal.hs +46/−0
- src/Data/Array/Accelerate/IO/Data/Array/Unboxed.hs +148/−0
- src/Data/Array/Accelerate/IO/Data/ByteString.hs +206/−0
- src/Data/Array/Accelerate/IO/Data/Vector/Generic.hs +57/−0
- src/Data/Array/Accelerate/IO/Data/Vector/Generic/Mutable.hs +263/−0
- src/Data/Array/Accelerate/IO/Data/Vector/Primitive.hs +140/−0
- src/Data/Array/Accelerate/IO/Data/Vector/Primitive/Internal.hs +82/−0
- src/Data/Array/Accelerate/IO/Data/Vector/Storable.hs +197/−0
- src/Data/Array/Accelerate/IO/Data/Vector/Unboxed.hs +356/−0
- src/Data/Array/Accelerate/IO/Foreign/ForeignPtr.hs +175/−0
- src/Data/Array/Accelerate/IO/Foreign/Ptr.hs +101/−0
- src/Data/Array/Repa/Repr/Accelerate.hs +176/−0
- test/Test.hs +29/−0
- test/Test/Array/IArray.hs +148/−0
- test/Test/Array/Unboxed.hs +128/−0
- test/Test/Util.hs +122/−0
- test/Test/Vector/Storable.hs +184/−0
- test/Test/Vector/Unboxed.hs +113/−0
CHANGELOG.md view
@@ -6,15 +6,33 @@ project adheres to the [Haskell Package Versioning Policy (PVP)](https://pvp.haskell.org) +## [1.2.0.0] - 2018-04-03+### Changed+ * Split the different conversion functions into separate modules, rather than having a single `Data.Array.Accelerate.IO` module which export everything.+ * Conversion to/from `ByteString` is now non-copying++### Added+ * Conversions between `Data.Vector.Unboxed`+ * Instances for `Data.Vector.Generic`+ * Support for AoS representations++### Fixed+ * Image created by `writeImageToBMP` flipped vertically ([#289])++ ## [1.0.0.1] - 2017-10-14 ### Fixed- * `fromIArray` would fail with exception "Error in array index" when the IArray- indices were not zero-based. This has been fixed.+ * `fromIArray` would fail with exception "Error in array index" when the IArray indices were not zero-based. This has been fixed. + ## [1.0.0.0] - 2017-03-31 * stable release -[1.1.0.0]: https://github.com/AccelerateHS/accelerate-llvm/compare/1.0.0.0...1.0.0.1-[1.0.0.0]: https://github.com/AccelerateHS/accelerate-llvm/compare/0.15.1.0...1.0.0.0+[1.2.0.0]: https://github.com/AccelerateHS/accelerate-io/compare/1.0.0.1...1.2.0.0+[1.0.0.1]: https://github.com/AccelerateHS/accelerate-io/compare/1.0.0.0...1.0.0.1+[1.0.0.0]: https://github.com/AccelerateHS/accelerate-io/compare/0.15.1.0...1.0.0.0+++[#289]: https://github.com/AccelerateHS/accelerate/issues/289
− Data/Array/Accelerate/IO.hs
@@ -1,47 +0,0 @@--- |--- Module : Data.Array.Accelerate.IO--- Copyright : [2010..2012] Sean Seefried--- [2010..2016] Trevor L. McDonell--- License : BSD3------ Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>--- Stability : experimental--- Portability : non-portable (GHC extensions)------ This module provides efficient conversion routines between different array--- types and Accelerate arrays.-----module Data.Array.Accelerate.IO (-- -- * Array libraries- module Data.Array.Accelerate.IO.Repa,- module Data.Array.Accelerate.IO.Vector,- module Data.Array.Accelerate.IO.IArray,-- -- * Specialised file IO- module Data.Array.Accelerate.IO.BMP,-- -- * Low-level conversions- --- -- | Copying conversions of low-level primitive data, stored in- -- one-dimensional row-major blocks of contiguous memory. To use these, you- -- should really know what you are doing. Potential pitfalls include:- --- -- * copying from memory your program doesn't have access to (e.g. it may be- -- unallocated, or not enough memory is allocated)- --- -- * memory alignment errors- --- module Data.Array.Accelerate.IO.ByteString,- module Data.Array.Accelerate.IO.Ptr,--) where--import Data.Array.Accelerate.IO.BMP-import Data.Array.Accelerate.IO.ByteString-import Data.Array.Accelerate.IO.IArray-import Data.Array.Accelerate.IO.Ptr-import Data.Array.Accelerate.IO.Repa-import Data.Array.Accelerate.IO.Vector-
− Data/Array/Accelerate/IO/BMP.hs
@@ -1,62 +0,0 @@--- |--- Module : Data.Array.Accelerate.IO.BMP--- Copyright : [2012..2014] Trevor L. McDonell--- License : BSD3------ Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>--- Stability : experimental--- Portability : non-portable (GHC extensions)------ Read and write BMP images into a packed-word RGBA format. See the--- /colour-accelerate/ package for colour representations and utilities such as--- packing and unpacking.-----module Data.Array.Accelerate.IO.BMP (-- -- ** Bitmap images- --- -- | Reading and writing arrays as uncompressed 24 or 32-bit Windows BMP- -- files.- --- RGBA32,- readImageFromBMP, writeImageToBMP,--) where--import Data.Word-import Codec.BMP--import Data.Array.Accelerate as A-import Data.Array.Accelerate.IO.ByteString as A----- | Packed RGBA pixel data----type RGBA32 = Word32---- File IO ------------------------------------------------------------------------- | Read RGBA components from a BMP file.----readImageFromBMP :: FilePath -> IO (Either Error (Array DIM2 RGBA32))-readImageFromBMP file = do- ebmp <- readBMP file- case ebmp of- Left err -> return $ Left err- Right bmp -> do- let (w,h) = bmpDimensions bmp- bs = unpackBMPToRGBA32 bmp- --- Right `fmap` A.fromByteString (Z :. h :. w) bs----- | Write the image data to a file.----writeImageToBMP :: FilePath -> Array DIM2 RGBA32 -> IO ()-writeImageToBMP file rgba = do- let Z :. h :. w = A.arrayShape rgba- bs <- A.toByteString rgba- --- writeBMP file (packRGBA32ToBMP w h bs)-
− Data/Array/Accelerate/IO/BlockCopy.hs
@@ -1,247 +0,0 @@-{-# LANGUAGE GADTs #-}-{-# LANGUAGE ForeignFunctionInterface #-}-{-# LANGUAGE MagicHash #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}--- |--- Module : Data.Array.Accelerate.IO.BlockCopy--- Copyright : [2010..2011] Sean Seefried--- [2010..2014] Trevor L. McDonell--- License : BSD3------ Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>--- Stability : experimental--- Portability : non-portable (GHC extensions)-----module Data.Array.Accelerate.IO.BlockCopy (-- -- * Types- BlockCopyFun, BlockCopyFuns, BlockPtrs, ByteStrings,-- -- * The low-level machinery- allocateArray, blockCopy, blockCopyFunGenerator--) where---- standard libraries-import Foreign-import Foreign.C-import GHC.Base-import Data.Array.Base (wORD_SCALE, fLOAT_SCALE, dOUBLE_SCALE)-import Data.ByteString---- friends-import Data.Array.Accelerate.Array.Data-import Data.Array.Accelerate.Array.Sugar----- | Functions of this type are passed as arguments to 'toArray'. A function of--- this type should copy a number of bytes (equal to the value of the--- parameter of type 'Int') to the destination memory pointed to by @Ptr e@.----type BlockCopyFun e = Ptr e -> Int -> IO ()---- | Represents a collection of "block copy functions" (see 'BlockCopyFun'). The--- structure of the collection of 'BlockCopyFun's depends on the element type--- @e@.------ e.g.------ If @e :: Float@--- then @BlockCopyFuns (EltRepr e) :: ((), Ptr Float -> Int -> IO ())@------ If @e :: (Double, Float)@--- then @BlockCopyFuns (EltRepr e) :: (((), Ptr Double -> Int -> IO ()), Ptr Float -> Int -> IO ())@----type family BlockCopyFuns e--type instance BlockCopyFuns () = ()-type instance BlockCopyFuns Int = BlockCopyFun Int-type instance BlockCopyFuns Int8 = BlockCopyFun Int8-type instance BlockCopyFuns Int16 = BlockCopyFun Int16-type instance BlockCopyFuns Int32 = BlockCopyFun Int32-type instance BlockCopyFuns Int64 = BlockCopyFun Int64-type instance BlockCopyFuns Word = BlockCopyFun Word-type instance BlockCopyFuns Word8 = BlockCopyFun Word8-type instance BlockCopyFuns Word16 = BlockCopyFun Word16-type instance BlockCopyFuns Word32 = BlockCopyFun Word32-type instance BlockCopyFuns Word64 = BlockCopyFun Word64-type instance BlockCopyFuns CShort = BlockCopyFun Int16-type instance BlockCopyFuns CUShort = BlockCopyFun Word16-type instance BlockCopyFuns CInt = BlockCopyFun Int32-type instance BlockCopyFuns CUInt = BlockCopyFun Word32-type instance BlockCopyFuns CLong = BlockCopyFun HTYPE_LONG-type instance BlockCopyFuns CULong = BlockCopyFun HTYPE_UNSIGNED_LONG-type instance BlockCopyFuns CLLong = BlockCopyFun Int64-type instance BlockCopyFuns CULLong = BlockCopyFun Word64-type instance BlockCopyFuns Float = BlockCopyFun Float-type instance BlockCopyFuns Double = BlockCopyFun Double-type instance BlockCopyFuns CFloat = BlockCopyFun Float-type instance BlockCopyFuns CDouble = BlockCopyFun Double-type instance BlockCopyFuns Bool = BlockCopyFun Word8-type instance BlockCopyFuns Char = BlockCopyFun Char-type instance BlockCopyFuns CChar = BlockCopyFun HTYPE_CCHAR-type instance BlockCopyFuns CSChar = BlockCopyFun Int8-type instance BlockCopyFuns CUChar = BlockCopyFun Word8-type instance BlockCopyFuns (a,b) = (BlockCopyFuns a, BlockCopyFuns b)---- | A family of types that represents a collection of pointers that are the--- source/destination addresses for a block copy. The structure of the--- collection of pointers depends on the element type @e@.------ e.g.------ If @e :: Int@, then @BlockPtrs (EltRepr e) :: ((), Ptr Int)@------ If @e :: (Double, Float)@ then @BlockPtrs (EltRepr e) :: (((), Ptr Double), Ptr Float)@----type family BlockPtrs e--type instance BlockPtrs () = ()-type instance BlockPtrs Int = Ptr Int-type instance BlockPtrs Int8 = Ptr Int8-type instance BlockPtrs Int16 = Ptr Int16-type instance BlockPtrs Int32 = Ptr Int32-type instance BlockPtrs Int64 = Ptr Int64-type instance BlockPtrs Word = Ptr Word-type instance BlockPtrs Word8 = Ptr Word8-type instance BlockPtrs Word16 = Ptr Word16-type instance BlockPtrs Word32 = Ptr Word32-type instance BlockPtrs Word64 = Ptr Word64-type instance BlockPtrs CShort = Ptr Int16-type instance BlockPtrs CUShort = Ptr Word16-type instance BlockPtrs CInt = Ptr Int32-type instance BlockPtrs CUInt = Ptr Word32-type instance BlockPtrs CLong = Ptr HTYPE_LONG-type instance BlockPtrs CULong = Ptr HTYPE_UNSIGNED_LONG-type instance BlockPtrs CLLong = Ptr Int64-type instance BlockPtrs CULLong = Ptr Word64-type instance BlockPtrs Float = Ptr Float-type instance BlockPtrs Double = Ptr Double-type instance BlockPtrs CFloat = Ptr Float-type instance BlockPtrs CDouble = Ptr Double-type instance BlockPtrs Bool = Ptr Word8-type instance BlockPtrs Char = Ptr Char-type instance BlockPtrs CChar = Ptr HTYPE_CCHAR-type instance BlockPtrs CSChar = Ptr Int8-type instance BlockPtrs CUChar = Ptr Word8-type instance BlockPtrs (a,b) = (BlockPtrs a, BlockPtrs b)---- | A family of types that represents a collection of 'ByteString's. They are--- the source data for function 'fromByteString' and the result data for--- 'toByteString'----type family ByteStrings e--type instance ByteStrings () = ()-type instance ByteStrings Int = ByteString-type instance ByteStrings Int8 = ByteString-type instance ByteStrings Int16 = ByteString-type instance ByteStrings Int32 = ByteString-type instance ByteStrings Int64 = ByteString-type instance ByteStrings Word = ByteString-type instance ByteStrings Word8 = ByteString-type instance ByteStrings Word16 = ByteString-type instance ByteStrings Word32 = ByteString-type instance ByteStrings Word64 = ByteString-type instance ByteStrings CShort = ByteString-type instance ByteStrings CUShort = ByteString-type instance ByteStrings CInt = ByteString-type instance ByteStrings CUInt = ByteString-type instance ByteStrings CLong = ByteString-type instance ByteStrings CULong = ByteString-type instance ByteStrings CLLong = ByteString-type instance ByteStrings CULLong = ByteString-type instance ByteStrings CShort = ByteString-type instance ByteStrings Float = ByteString-type instance ByteStrings Double = ByteString-type instance ByteStrings CFloat = ByteString-type instance ByteStrings CDouble = ByteString-type instance ByteStrings Bool = ByteString-type instance ByteStrings Char = ByteString-type instance ByteStrings CChar = ByteString-type instance ByteStrings CSChar = ByteString-type instance ByteStrings CUChar = ByteString-type instance ByteStrings (a,b) = (ByteStrings a, ByteStrings b)---type GenFuns e = (( BlockPtrs e -> IO ()- , ByteStrings e -> IO ())- ,( BlockPtrs e -> IO ()- , IO (ByteStrings e))- , BlockCopyFuns e -> IO ())--base :: forall a b. Ptr b -> Int -> (( Ptr a -> IO (), ByteString -> IO ())- ,( Ptr a -> IO (), IO ByteString)- ,(Ptr b -> Int -> IO ()) -> IO ())-base accArrayPtr byteSize =- ((blockPtrToArray, byteStringToArray)- ,(arrayToBlockPtr, arrayToByteString)- , blockCopyFunToOrFromArray)- where- blockPtrToArray :: Ptr a -> IO ()- blockPtrToArray blockPtr = blockCopy blockPtr accArrayPtr byteSize- arrayToBlockPtr :: Ptr a -> IO ()- arrayToBlockPtr blockPtr = blockCopy accArrayPtr blockPtr byteSize- blockCopyFunToOrFromArray :: (Ptr b -> Int -> IO ()) -> IO ()- blockCopyFunToOrFromArray blockCopyFun = blockCopyFun accArrayPtr byteSize- byteStringToArray :: ByteString -> IO ()- byteStringToArray bs = useAsCString bs (blockPtrToArray . castPtr)- arrayToByteString :: IO ByteString- arrayToByteString = packCStringLen (castPtr accArrayPtr, byteSize)--blockCopyFunGenerator :: Array sh e -> GenFuns (EltRepr e)-blockCopyFunGenerator array@(Array _ arrayData) = aux arrayElt arrayData- where- sizeA = size (shape array)- aux :: ArrayEltR e -> ArrayData e -> GenFuns e- aux ArrayEltRunit _ = let f () = return () in ((f,f),(f,return ()),f)- aux ArrayEltRint ad = base (ptrsOfArrayData ad) (box wORD_SCALE sizeA)- aux ArrayEltRint8 ad = base (ptrsOfArrayData ad) sizeA- aux ArrayEltRint16 ad = base (ptrsOfArrayData ad) (sizeA * 2)- aux ArrayEltRint32 ad = base (ptrsOfArrayData ad) (sizeA * 4)- aux ArrayEltRint64 ad = base (ptrsOfArrayData ad) (sizeA * 8)- aux ArrayEltRword ad = base (ptrsOfArrayData ad) (box wORD_SCALE sizeA)- aux ArrayEltRword8 ad = base (ptrsOfArrayData ad) sizeA- aux ArrayEltRword16 ad = base (ptrsOfArrayData ad) (sizeA * 2)- aux ArrayEltRword32 ad = base (ptrsOfArrayData ad) (sizeA * 4)- aux ArrayEltRword64 ad = base (ptrsOfArrayData ad) (sizeA * 8)- aux ArrayEltRcshort ad = base (ptrsOfArrayData ad) (sizeA * 2)- aux ArrayEltRcushort ad = base (ptrsOfArrayData ad) (sizeA * 2)- aux ArrayEltRcint ad = base (ptrsOfArrayData ad) (sizeA * 4)- aux ArrayEltRcuint ad = base (ptrsOfArrayData ad) (sizeA * 4)- aux ArrayEltRclong ad = base (ptrsOfArrayData ad) (sizeA * 8)- aux ArrayEltRculong ad = base (ptrsOfArrayData ad) (sizeA * 8)- aux ArrayEltRcllong ad = base (ptrsOfArrayData ad) (sizeA * 8)- aux ArrayEltRcullong ad = base (ptrsOfArrayData ad) (sizeA * 8)- aux ArrayEltRfloat ad = base (ptrsOfArrayData ad) (box fLOAT_SCALE sizeA)- aux ArrayEltRcfloat ad = base (ptrsOfArrayData ad) (box fLOAT_SCALE sizeA)- aux ArrayEltRdouble ad = base (ptrsOfArrayData ad) (box dOUBLE_SCALE sizeA)- aux ArrayEltRcdouble ad = base (ptrsOfArrayData ad) (box dOUBLE_SCALE sizeA)- aux ArrayEltRbool ad = base (ptrsOfArrayData ad) sizeA- aux ArrayEltRchar ad = base (ptrsOfArrayData ad) (sizeA * 4)- aux ArrayEltRcchar ad = base (ptrsOfArrayData ad) sizeA- aux ArrayEltRcschar ad = base (ptrsOfArrayData ad) sizeA- aux ArrayEltRcuchar ad = base (ptrsOfArrayData ad) sizeA- aux (ArrayEltRpair a b) (AD_Pair ad1 ad2) = ((bpFromC, bsFromC), (bpToC, bsToC), toH)- where- ((bpFromC1, bsFromC1), (bpToC1, bsToC1), toH1) = aux a ad1- ((bpFromC2, bsFromC2), (bpToC2, bsToC2), toH2) = aux b ad2- toH (funs1, funs2) = toH1 funs1 >> toH2 funs2- bpToC (ptrA, ptrB) = bpToC1 ptrA >> bpToC2 ptrB- bsToC = do { bsA <- bsToC1; bsB <- bsToC2; return (bsA, bsB) }- bpFromC (ptrA, ptrB) = bpFromC1 ptrA >> bpFromC2 ptrB- bsFromC (bsA, bsB) = bsFromC1 bsA >> bsFromC2 bsB--blockCopy :: Ptr a -> Ptr b -> Int -> IO ()-blockCopy src dst byteSize = memcpy dst src (fromIntegral byteSize)----- Foreign imports-foreign import ccall memcpy :: Ptr a -> Ptr b -> CInt -> IO ()---- Helpers-box :: (Int# -> Int#) -> Int -> Int-box f (I# x) = I# (f x)-
− Data/Array/Accelerate/IO/ByteString.hs
@@ -1,49 +0,0 @@--- |--- Module : Data.Array.Accelerate.IO.ByteString--- Copyright : [2010..2011] Sean Seefried--- [2010..2014] Trevor L. McDonell--- License : BSD3------ Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>--- Stability : experimental--- Portability : non-portable (GHC extensions)-----module Data.Array.Accelerate.IO.ByteString (-- -- ** Data.ByteString- ByteStrings, fromByteString, toByteString--) where--import Data.Array.Accelerate.IO.BlockCopy-import Data.Array.Accelerate.Array.Sugar----- | Block copies bytes from a collection of 'ByteString's to freshly allocated--- Accelerate array.------ The type of elements (@e@) in the output Accelerate array determines the--- structure of the collection of 'ByteString's that will be required as the--- second argument to this function. See 'ByteStrings'----fromByteString :: (Shape sh, Elt e) => sh -> ByteStrings (EltRepr e) -> IO (Array sh e)-fromByteString sh byteStrings = do- arr <- allocateArray sh- let copier = let ((_,f),_,_) = blockCopyFunGenerator arr in f- copier byteStrings- return arr----- | Block copy from an Accelerate array to a collection of freshly allocated--- 'ByteString's.------ The type of elements (@e@) in the input Accelerate array determines the--- structure of the collection of 'ByteString's that will be output. See--- 'ByteStrings'----toByteString :: (Shape sh, Elt e) => Array sh e -> IO (ByteStrings (EltRepr e))-toByteString arr = do- let copier = let (_,(_,f),_) = blockCopyFunGenerator arr in f- copier-
− Data/Array/Accelerate/IO/IArray.hs
@@ -1,97 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeFamilies #-}--- |--- Module : Data.Array.Accelerate.IO.IArray--- Copyright : [2016] Trevor L. McDonell--- License : BSD3------ Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>--- Stability : experimental--- Portability : non-portable (GHC extensions)------ Convert immutable arrays of the <https://hackage.haskell.org/package/array--- array> library into Accelerate 'Array's.-----module Data.Array.Accelerate.IO.IArray (-- -- ** 'Data.Array.IArray.IArray'- fromIArray,- toIArray,--) where--import Data.Array.Accelerate.Array.Sugar-import Data.Array.Accelerate.Type--import Data.Array.IArray ( IArray )-import qualified Data.Array.IArray as IArray----- | 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- :: (IxShapeRepr (EltRepr ix) ~ EltRepr sh, IArray a e, IArray.Ix ix, Shape sh, Elt ix, Elt e)- => a ix e- -> Array sh e-fromIArray iarr = fromFunction sh (\ix -> iarr IArray.! fromIxShapeRepr (offset lo' ix))- where- (lo,hi) = IArray.bounds iarr- lo' = toIxShapeRepr lo- hi' = toIxShapeRepr hi- sh = rangeToShape (lo', hi')-- -- IArray does not necessarily start indexing from zero. Thus, we need to- -- add some offset to the Accelerate indices to map them onto the valid- -- index range of the IArray- --- offset :: forall sh. Shape sh => sh -> sh -> sh- offset ix0 ix = toElt $ go (eltType (undefined::sh)) (fromElt ix0) (fromElt ix)- where- go :: TupleType ix -> ix -> ix -> ix- go UnitTuple () () = ()- go (PairTuple tl tr) (l0, r0) (l,r) = (go tl l0 l, go tr r0 r)- go (SingleTuple (NumScalarType (IntegralNumType TypeInt{}))) i0 i = i0+i- go _ _ _- = error "Data.Array.Accelerate.IO.IArray: error in index offset"---- | Convert an accelerated array to an 'IArray'.----toIArray- :: (IxShapeRepr (EltRepr ix) ~ EltRepr sh, IArray a e, IArray.Ix ix, Shape sh, Elt ix)- => Array sh e- -> a ix e-toIArray arr = IArray.array bnds [(ix, arr ! toIxShapeRepr ix) | ix <- IArray.range bnds]- where- (lo,hi) = shapeToRange (shape arr)- bnds = (fromIxShapeRepr lo, fromIxShapeRepr hi)---type family IxShapeRepr e where- IxShapeRepr () = ()- IxShapeRepr Int = ((),Int)- IxShapeRepr (t,h) = (IxShapeRepr t, h)--fromIxShapeRepr :: forall ix sh. (IxShapeRepr (EltRepr ix) ~ EltRepr sh, Shape sh, Elt ix) => sh -> ix-fromIxShapeRepr sh = toElt (go (eltType (undefined::ix)) (fromElt sh))- where- go :: forall ix'. TupleType ix' -> IxShapeRepr ix' -> ix'- go UnitTuple () = ()- go (SingleTuple (NumScalarType (IntegralNumType TypeInt{}))) ((),h) = h- go (PairTuple tt _) (t, h) = (go tt t, h)- go _ _ = error "Data.Array.Accelerate.IO.IArray: not a valid IArray.Ix"--toIxShapeRepr :: forall ix sh. (IxShapeRepr (EltRepr ix) ~ EltRepr sh, Shape sh, Elt ix) => ix -> sh-toIxShapeRepr ix = toElt (go (eltType (undefined::ix)) (fromElt ix))- where- go :: forall ix'. TupleType ix' -> ix' -> IxShapeRepr ix'- go UnitTuple () = ()- go (SingleTuple (NumScalarType (IntegralNumType TypeInt{}))) h = ((), h)- go (PairTuple tt _) (t, h) = (go tt t, h)- go _ _ = error "Data.Array.Accelerate.IO.IArray: not a valid IArray.Ix"-
− Data/Array/Accelerate/IO/Ptr.hs
@@ -1,100 +0,0 @@--- |--- Module : Data.Array.Accelerate.IO.Ptr--- Copyright : [2010..2011] Sean Seefried--- [2010..2014] Trevor L. McDonell--- License : BSD3------ Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>--- Stability : experimental--- Portability : non-portable (GHC extensions)-----module Data.Array.Accelerate.IO.Ptr (-- -- ** Raw pointers- BlockPtrs, fromPtr, toPtr,-- -- ** Direct copying functions- BlockCopyFun, BlockCopyFuns, fromArray, toArray--) where--import Data.Array.Accelerate.IO.BlockCopy-import Data.Array.Accelerate.Array.Sugar----- | Block copy regions of memory into a freshly allocated Accelerate array. The--- type of elements (@e@) in the output Accelerate array determines the--- structure of the collection of pointers that will be required as the second--- argument to this function. See 'BlockPtrs'------ Each one of these pointers points to a block of memory that is the source--- of data for the Accelerate array (unlike function 'toArray' where one--- passes in function which copies data to a destination address.).----fromPtr :: (Shape sh, Elt e) => sh -> BlockPtrs (EltRepr e) -> IO (Array sh e)-fromPtr sh blkPtrs = do- arr <- allocateArray sh- let copier = let ((f,_),_,_) = blockCopyFunGenerator arr in f- copier blkPtrs- return arr----- | Block copy from Accelerate array to pre-allocated regions of memory. The--- type of element of the input Accelerate array (@e@) determines the--- structure of the collection of pointers that will be required as the second--- argument to this function. See 'BlockPtrs'------ The memory associated with the pointers must have already been allocated.----toPtr :: (Shape sh, Elt e) => Array sh e -> BlockPtrs (EltRepr e) -> IO ()-toPtr arr blockPtrs = do- let copier = let (_,(f,_),_) = blockCopyFunGenerator arr in f- copier blockPtrs- return ()----- | Copy values from an Accelerate array using a collection of functions that--- have type 'BlockCopyFun'. The argument of type @Ptr e@ in each of these--- functions refers to the address of the /source/ block of memory in the--- Accelerate Array. The /destination/ address is implicit. e.g. the--- 'BlockCopyFun' could be the result of partially application to a @Ptr e@--- pointing to the destination block.------ The structure of this collection of functions depends on the elemente type--- @e@. Each function (of type 'BlockCopyFun') copies data to a destination--- address (pointed to by the argument of type @Ptr ()@).------ Unless there is a particularly pressing reason to use this function, the--- 'fromPtr' function is sufficient as it uses an efficient low-level call to--- libc's @memcpy@ to perform the copy.----fromArray :: (Shape sh, Elt e) => Array sh e -> BlockCopyFuns (EltRepr e) -> IO ()-fromArray arr blockCopyFuns = do- let copier = let (_,_,f) = blockCopyFunGenerator arr in f- copier blockCopyFuns- return ()----- | Copy values to a freshly allocated Accelerate array using a collection of--- functions that have type 'BlockCopyFun'. The argument of type @Ptr e@ in--- each of these functions refers to the address of the /destination/ block of--- memory in the Accelerate Array. The /source/ address is implicit. e.g. the--- 'BlockCopyFun' could be the result of a partial application to a @Ptr e@--- pointing to the source block.------ The structure of this collection of functions depends on the elemente type--- @e@. Each function (of type 'BlockCopyFun') copies data to a destination--- address (pointed to by the argument of type @Ptr ()@).------ Unless there is a particularly pressing reason to use this function, the--- 'fromPtr' function is sufficient as it uses an efficient low-level call to--- libc's @memcpy@ to perform the copy.----toArray :: (Shape sh, Elt e) => sh -> BlockCopyFuns (EltRepr e) -> IO (Array sh e)-toArray sh blockCopyFuns = do- arr <- allocateArray sh- let copier = let (_,_,f) = blockCopyFunGenerator arr in f- copier blockCopyFuns- return arr-
− Data/Array/Accelerate/IO/Repa.hs
@@ -1,177 +0,0 @@-{-# LANGUAGE EmptyDataDecls #-}-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE ExplicitForAll #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FunctionalDependencies #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE UndecidableInstances #-}--- |--- Module : Data.Array.Accelerate.IO.Repa--- Copyright : [2012..2014] Trevor L. McDonell--- License : BSD3------ Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>--- Stability : experimental--- Portability : non-portable (GHC extensions)-----module Data.Array.Accelerate.IO.Repa (-- -- ** Data.Array.Repa- --- -- | This provides an efficient non-copying Repa manifest array representation- -- that can be passed directly to Accelerate.- --- -- The standard rules for dealing with manifest Repa arrays apply:- --- -- * If you want to have Repa 'R.computeP' directly into an Accelerate array,- -- the source array must have a delayed representation.- --- -- * If you want to copy between manifest arrays, use 'R.copyP' instead.- --- A, Shapes,- fromRepa, toRepa,- computeAccS, computeAccP--) where--import Control.Monad--import qualified Data.Array.Repa as R-import qualified Data.Array.Repa.Eval as R-import qualified Data.Array.Accelerate.Array.Data as A-import qualified Data.Array.Accelerate.Array.Sugar as A----- | Index conversion and equivalence statement between Repa and Accelerate--- array shapes. That is, a n-dimensional Repa array will produce an--- n-dimensional Accelerate array of the same extent, and vice-versa.----class (R.Shape r, A.Shape a) => Shapes r a | a -> r, r -> a where- -- these are really equivalent representations, so unsafeCoerce would probably- -- work, but bad programmers get no cookies.- toR :: a -> r- toA :: r -> a--instance Shapes R.Z A.Z where- {-# INLINE toR #-}- toR A.Z = R.Z- {-# INLINE toA #-}- toA R.Z = A.Z--instance Shapes sr sa => Shapes (sr R.:. Int) (sa A.:. Int) where- {-# INLINE toR #-}- toR (sa A.:. sz) = toR sa R.:. sz- {-# INLINE toA #-}- toA (sr R.:. sz) = toA sr A.:. sz----- | The representation tag for manifest arrays based on Data.Array.Accelerate.------ The Accelerate array implementation is based on type families and picks an--- efficient, unboxed representation for every element type. Moreover, these--- arrays can be handed efficiently (without copying) to Accelerate programs--- for further computation.----data A---- Repr ---------------------------------------------------------------------------- | Reading elements of the Accelerate array----instance A.Elt e => R.Source A e where- data Array A sh e- = AAccelerate !sh !(A.ArrayData (A.EltRepr e))-- {-# INLINE extent #-}- extent (AAccelerate sh _)- = sh-- {-# INLINE linearIndex #-}- linearIndex (AAccelerate sh adata) ix- | ix >= 0 && ix < R.size sh- = A.toElt (adata `A.unsafeIndexArrayData` ix)-- | otherwise- = error "Repa: accelerate array out of bounds"-- {-# INLINE unsafeLinearIndex #-}- unsafeLinearIndex (AAccelerate _ adata) ix- = A.toElt (adata `A.unsafeIndexArrayData` ix)-- {-# INLINE deepSeqArray #-}- deepSeqArray (AAccelerate sh adata) x- = sh `R.deepSeq` adata `seq` x----- | Filling Accelerate arrays----instance A.Elt e => R.Target A e where- data MVec A e- = MAVec (A.MutableArrayData (A.EltRepr e))-- {-# INLINE newMVec #-}- newMVec n- = MAVec `liftM` A.newArrayData n-- {-# INLINE unsafeWriteMVec #-}- unsafeWriteMVec (MAVec mad) n e- = A.unsafeWriteArrayData mad n (A.fromElt e)-- {-# INLINE unsafeFreezeMVec #-}- unsafeFreezeMVec sh (MAVec mad)- = do adata <- A.unsafeFreezeArrayData mad- return $! AAccelerate sh adata-- {-# INLINE deepSeqMVec #-}- deepSeqMVec (MAVec arr) x -- maybe?- = arr `seq` x-- {-# INLINE touchMVec #-}- touchMVec _ -- maybe?- = return ()----- Conversions --------------------------------------------------------------------- | /O(1)/. Wrap an Accelerate array.----toRepa- :: Shapes sh sh'- => A.Array sh' e -> R.Array A sh e-{-# INLINE toRepa #-}-toRepa arr@(A.Array _ adata)- = AAccelerate (toR (A.shape arr)) adata---- | /O(1)/. Unpack to an Accelerate array.----fromRepa- :: (Shapes sh sh', A.Elt e)- => R.Array A sh e -> A.Array sh' e-{-# INLINE fromRepa #-}-fromRepa (AAccelerate sh adata)- = A.Array (A.fromElt (toA sh)) adata----- Computations -------------------------------------------------------------------- | Sequential computation of array elements----computeAccS- :: (R.Load r sh e, A.Elt e)- => R.Array r sh e -> R.Array A sh e-{-# INLINE computeAccS #-}-computeAccS = R.computeS---- | Parallel computation of array elements----computeAccP- :: (R.Load r sh e, A.Elt e, Monad m)- => R.Array r sh e- -> m (R.Array A sh e)-{-# INLINE computeAccP #-}-computeAccP = R.computeP-
− Data/Array/Accelerate/IO/Vector.hs
@@ -1,172 +0,0 @@-{-# LANGUAGE GADTs #-}-{-# LANGUAGE TypeFamilies #-}--- |--- Module : Data.Array.Accelerate.IO.Vector--- Copyright : [2012] Adam C. Foltzer--- [2012..2015] Trevor L. McDonell--- License : BSD3------ Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>--- Stability : experimental--- Portability : non-portable (GHC extensions)------ Helpers for fast conversion between 'Data.Vector.Storable' vectors into--- Accelerate arrays.-----module Data.Array.Accelerate.IO.Vector (-- -- ** Data.Vector.Storable- --- -- | This provides an efficient non-copying conversion between storable- -- vectors and Accelerate arrays.- --- Vectors, toVectors, fromVectors,--) where---- standard libraries-import Data.Int-import Data.Word-import Foreign.C.Types-import Data.Vector.Storable-import System.IO.Unsafe---- friends-import Data.Array.Accelerate.Lifetime-import Data.Array.Accelerate.Array.Unique-import Data.Array.Accelerate.Array.Data-import Data.Array.Accelerate.Array.Sugar hiding ( Vector, size )-import Data.Array.Accelerate.Array.Representation ( size )----- | A family of types that represents a collection of storable 'Vector's. The--- structure of the collection depends on the element type @e@.------ For example:------ * if @e :: Int@, then @Vectors (EltRepr e) :: ((), Vector Int)@------ * if @e :: (Double, Float)@, then @Vectors (EltRepr e) :: (((), Vector Double), Vector Float)@----type family Vectors e--type instance Vectors () = ()-type instance Vectors Int = Vector Int-type instance Vectors Int8 = Vector Int8-type instance Vectors Int16 = Vector Int16-type instance Vectors Int32 = Vector Int32-type instance Vectors Int64 = Vector Int64-type instance Vectors Word = Vector Word-type instance Vectors Word8 = Vector Word8-type instance Vectors Word16 = Vector Word16-type instance Vectors Word32 = Vector Word32-type instance Vectors Word64 = Vector Word64-type instance Vectors CShort = Vector Int16-type instance Vectors CUShort = Vector Word16-type instance Vectors CInt = Vector Int32-type instance Vectors CUInt = Vector Word32-type instance Vectors CLong = Vector HTYPE_LONG-type instance Vectors CULong = Vector HTYPE_UNSIGNED_LONG-type instance Vectors CLLong = Vector Int64-type instance Vectors CULLong = Vector Word64-type instance Vectors Float = Vector Float-type instance Vectors CFloat = Vector Float-type instance Vectors Double = Vector Double-type instance Vectors CDouble = Vector Double-type instance Vectors Bool = Vector Word8-type instance Vectors Char = Vector Char-type instance Vectors CChar = Vector HTYPE_CCHAR-type instance Vectors CSChar = Vector Int8-type instance Vectors CUChar = Vector Word8-type instance Vectors (a,b) = (Vectors a, Vectors b)----- | /O(1)/. Treat a set of storable vectors as Accelerate arrays. The type of--- elements @e@ in the output Accelerate array determines the structure of the--- collection that will be required as the second argument. See 'Vectors'.------ Data will be consumed from the vector in row-major order. You must make sure--- that each of the input vectors contains the right number of elements----fromVectors :: (Shape sh, Elt e) => sh -> Vectors (EltRepr e) -> Array sh e-fromVectors sh vecs = Array (fromElt sh) (aux arrayElt vecs)- where- wrap k v = let (fp,_) = unsafeToForeignPtr0 v- in k (unsafePerformIO $ newUniqueArray fp)-- aux :: ArrayEltR e -> Vectors e -> ArrayData e- aux ArrayEltRunit = const AD_Unit- aux ArrayEltRint = wrap AD_Int- aux ArrayEltRint8 = wrap AD_Int8- aux ArrayEltRint16 = wrap AD_Int16- aux ArrayEltRint32 = wrap AD_Int32- aux ArrayEltRint64 = wrap AD_Int64- aux ArrayEltRword = wrap AD_Word- aux ArrayEltRword8 = wrap AD_Word8- aux ArrayEltRword16 = wrap AD_Word16- aux ArrayEltRword32 = wrap AD_Word32- aux ArrayEltRword64 = wrap AD_Word64- aux ArrayEltRcshort = wrap AD_CShort- aux ArrayEltRcushort = wrap AD_CUShort- aux ArrayEltRcint = wrap AD_CInt- aux ArrayEltRcuint = wrap AD_CUInt- aux ArrayEltRclong = wrap AD_CLong- aux ArrayEltRculong = wrap AD_CULong- aux ArrayEltRcllong = wrap AD_CLLong- aux ArrayEltRcullong = wrap AD_CULLong- aux ArrayEltRfloat = wrap AD_Float- aux ArrayEltRdouble = wrap AD_Double- aux ArrayEltRcfloat = wrap AD_CFloat- aux ArrayEltRcdouble = wrap AD_CDouble- aux ArrayEltRbool = wrap AD_Bool- aux ArrayEltRchar = wrap AD_Char- aux ArrayEltRcchar = wrap AD_CChar- aux ArrayEltRcschar = wrap AD_CSChar- aux ArrayEltRcuchar = wrap AD_CUChar- aux (ArrayEltRpair ae1 ae2) = \(v1,v2) -> AD_Pair (aux ae1 v1) (aux ae2 v2)----- | /O(1)/. Turn the Accelerate array into a collection of storable 'Vector's.--- The element type of the array @e@ will determine the structure of the output--- collection. See 'Vectors'.------ Data will be output in row-major order.----toVectors :: (Shape sh, Elt e) => Array sh e -> Vectors (EltRepr e)-toVectors (Array sh adata) = aux arrayElt adata- where- wrap :: Storable a => UniqueArray a -> Vector a- wrap ua = unsafeFromForeignPtr0 (unsafeGetValue (uniqueArrayData ua)) (size sh)-- aux :: ArrayEltR e -> ArrayData e -> Vectors e- aux ArrayEltRunit AD_Unit = ()- aux ArrayEltRint (AD_Int s) = wrap s- aux ArrayEltRint8 (AD_Int8 s) = wrap s- aux ArrayEltRint16 (AD_Int16 s) = wrap s- aux ArrayEltRint32 (AD_Int32 s) = wrap s- aux ArrayEltRint64 (AD_Int64 s) = wrap s- aux ArrayEltRword (AD_Word s) = wrap s- aux ArrayEltRword8 (AD_Word8 s) = wrap s- aux ArrayEltRword16 (AD_Word16 s) = wrap s- aux ArrayEltRword32 (AD_Word32 s) = wrap s- aux ArrayEltRword64 (AD_Word64 s) = wrap s- aux ArrayEltRcshort (AD_CShort s) = wrap s- aux ArrayEltRcushort (AD_CUShort s) = wrap s- aux ArrayEltRcint (AD_CInt s) = wrap s- aux ArrayEltRcuint (AD_CUInt s) = wrap s- aux ArrayEltRclong (AD_CLong s) = wrap s- aux ArrayEltRculong (AD_CULong s) = wrap s- aux ArrayEltRcllong (AD_CLLong s) = wrap s- aux ArrayEltRcullong (AD_CULLong s) = wrap s- aux ArrayEltRfloat (AD_Float s) = wrap s- aux ArrayEltRdouble (AD_Double s) = wrap s- aux ArrayEltRcfloat (AD_CFloat s) = wrap s- aux ArrayEltRcdouble (AD_CDouble s) = wrap s- aux ArrayEltRbool (AD_Bool s) = wrap s- aux ArrayEltRchar (AD_Char s) = wrap s- aux ArrayEltRcchar (AD_CChar s) = wrap s- aux ArrayEltRcschar (AD_CSChar s) = wrap s- aux ArrayEltRcuchar (AD_CUChar s) = wrap s- aux (ArrayEltRpair ae1 ae2) (AD_Pair s1 s2) = (aux ae1 s1, aux ae2 s2)-
accelerate-io.cabal view
@@ -1,6 +1,6 @@ Name: accelerate-io-Version: 1.0.0.1-Cabal-version: >= 1.6+Version: 1.2.0.0+Cabal-version: >= 1.10 Tested-with: GHC >= 7.8 Build-type: Simple @@ -29,68 +29,98 @@ README.md CHANGELOG.md -Flag bounds-checks- Description: Enable bounds checking- Default: True--Flag unsafe-checks- Description: Enable bounds checking in unsafe operations- Default: False--Flag internal-checks- Description: Enable internal consistency checks- Default: False--Library- Build-depends:- base >= 4.7 && < 4.11- , accelerate >= 1.0+library+ build-depends:+ base >= 4.7 && < 4.12+ , accelerate >= 1.2 , array >= 0.3 , bmp >= 1.2 , bytestring >= 0.9+ , primitive >= 0.6 , repa >= 3.2 , vector >= 0.9 - Exposed-modules:- Data.Array.Accelerate.IO+ exposed-modules:+ -- bmp+ Data.Array.Accelerate.IO.Codec.BMP - Other-modules:- Data.Array.Accelerate.IO.BlockCopy- Data.Array.Accelerate.IO.BMP- Data.Array.Accelerate.IO.ByteString- Data.Array.Accelerate.IO.IArray- Data.Array.Accelerate.IO.Ptr- Data.Array.Accelerate.IO.Repa- Data.Array.Accelerate.IO.Vector+ -- bytestring+ Data.Array.Accelerate.IO.Data.ByteString + -- vector+ Data.Array.Accelerate.IO.Data.Vector.Generic+ Data.Array.Accelerate.IO.Data.Vector.Generic.Mutable+ Data.Array.Accelerate.IO.Data.Vector.Primitive+ Data.Array.Accelerate.IO.Data.Vector.Storable+ Data.Array.Accelerate.IO.Data.Vector.Unboxed++ -- array+ Data.Array.Accelerate.IO.Data.Array.IArray+ Data.Array.Accelerate.IO.Data.Array.Unboxed++ -- foeign+ Data.Array.Accelerate.IO.Foreign.Ptr+ Data.Array.Accelerate.IO.Foreign.ForeignPtr++ -- repa+ Data.Array.Repa.Repr.Accelerate++ other-modules:+ Data.Array.Accelerate.IO.Data.Array.Internal+ Data.Array.Accelerate.IO.Data.Vector.Primitive.Internal++ default-language:+ Haskell2010++ hs-source-dirs:+ src+ ghc-options: -O2 -Wall -funbox-strict-fields - if flag(bounds-checks)- cpp-options: -DACCELERATE_BOUNDS_CHECKS+ ghc-prof-options:+ -fprof-auto - if flag(unsafe-checks)- cpp-options: -DACCELERATE_UNSAFE_CHECKS - if flag(internal-checks)- cpp-options: -DACCELERATE_INTERNAL_CHECKS+test-suite test-io+ type: exitcode-stdio-1.0+ default-language: Haskell2010+ hs-source-dirs: test+ main-is: Test.hs+ ghc-options: -main-is Test - -- Don't add the extensions list here. Instead, place individual LANGUAGE- -- pragmas in the files that require a specific extension. This means the- -- project loads in GHCi, and avoids extension clashes.- --- -- Extensions:+ build-depends:+ base >= 4.7 && < 4.12+ , accelerate+ , accelerate-io+ , array+ , hedgehog >= 0.5+ , tasty >= 0.11+ , tasty-hedgehog >= 0.1+ , vector -Source-repository head+ ghc-options:+ -Wall+ -threaded+ -rtsopts++ other-modules:+ Test.Array.IArray+ Test.Array.Unboxed+ Test.Vector.Storable+ Test.Vector.Unboxed+ Test.Util+++source-repository head Type: git Location: git://github.com/AccelerateHS/accelerate-io.git -Source-repository this+source-repository this Type: git- Tag: 1.0.0.1+ Tag: 1.2.0.0 Location: git://github.com/AccelerateHS/accelerate-io.git -- vim: nospell-
+ src/Data/Array/Accelerate/IO/Codec/BMP.hs view
@@ -0,0 +1,82 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TemplateHaskell #-}+-- |+-- Module : Data.Array.Accelerate.IO.Codec.BMP+-- Copyright : [2012..2014] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--+-- Read and write uncompressed 24 or 32-bit Windows BMP images into+-- a packed-word RGBA format. See the /colour-accelerate/ package for colour+-- representations and utilities such as packing and unpacking.+--++module Data.Array.Accelerate.IO.Codec.BMP (++ RGBA32,+ readImageFromBMP, writeImageToBMP,++) where++import Data.Word+import Codec.BMP++import Data.Array.Accelerate.Array.Sugar+import Data.Array.Accelerate.IO.Data.ByteString+++-- | Packed RGBA pixel data+--+type RGBA32 = Word32+++-- File IO ---------------------------------------------------------------------++-- | Read RGBA components from a BMP file.+--+readImageFromBMP :: FilePath -> IO (Either Error (Array DIM2 RGBA32))+readImageFromBMP file = do+ ebmp <- readBMP file+ case ebmp of+ Left err -> return $ Left err+ Right bmp -> do+ let (w,h) = bmpDimensions bmp+ bs = unpackBMPToRGBA32 bmp'+ arr = fromByteStrings (Z :. h :. w) bs+ --+ bmp' = bmp { bmpBitmapInfo = info' }+ info' = case bmpBitmapInfo bmp of+ InfoV3 i -> InfoV3 (info3 i)+ InfoV4 i -> InfoV4 (info4 i)+ InfoV5 i -> InfoV5 (info5 i)++ info3 BitmapInfoV3{..} = BitmapInfoV3 { dib3HeightFlipped = not dib3HeightFlipped, .. }+ info4 BitmapInfoV4{..} = BitmapInfoV4 { dib4InfoV3 = info3 dib4InfoV3, .. }+ info5 BitmapInfoV5{..} = BitmapInfoV5 { dib5InfoV4 = info4 dib5InfoV4, .. }+ --+ return $ Right arr+++-- | Write the image data to a file.+--+writeImageToBMP :: FilePath -> Array DIM2 RGBA32 -> IO ()+writeImageToBMP file rgba = writeBMP file bmp'+ where+ Z :. h :. w = shape rgba+ bs = toByteStrings rgba+ bmp = packRGBA32ToBMP w h bs+ --+ bmp' = bmp { bmpBitmapInfo = info' }+ info' = case bmpBitmapInfo bmp of+ InfoV3 i -> InfoV3 (info3 i)+ InfoV4 i -> InfoV4 (info4 i)+ InfoV5 i -> InfoV5 (info5 i)++ info3 BitmapInfoV3{..} = BitmapInfoV3 { dib3Height = -dib3Height, dib3HeightFlipped = True, .. }+ info4 BitmapInfoV4{..} = BitmapInfoV4 { dib4InfoV3 = info3 dib4InfoV3, .. }+ info5 BitmapInfoV5{..} = BitmapInfoV5 { dib5InfoV4 = info4 dib5InfoV4, .. }+
+ src/Data/Array/Accelerate/IO/Data/Array/IArray.hs view
@@ -0,0 +1,107 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}+-- |+-- Module : Data.Array.Accelerate.IO.Data.Array.IArray+-- Copyright : [2016..2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--+-- Convert between immutable 'IArray's and Accelerate 'Array's.+--++module Data.Array.Accelerate.IO.Data.Array.IArray (++ IxShapeRepr,+ fromIArray,+ toIArray,++) where++import Data.Array.Accelerate.Array.Sugar+import Data.Array.Accelerate.Type+import Data.Array.Accelerate.Error++import Data.Array.Accelerate.IO.Data.Array.Internal++import Data.Array.IArray ( IArray )+import qualified Data.Array.IArray as IArray+++-- | /O(n)/. Convert an 'IArray' to an Accelerate 'Array'.+--+-- The index type @ix@ of the 'IArray' corresponds to the shape @sh@ of the+-- Accelerate 'Array' in the following way:+--+-- > DIM0 ~ ()+-- > DIM1 ~ Int+-- > DIM2 ~ (Int,Int)+-- > DIM3 ~ (Int,Int,Int)+--+-- ...and so forth.+--+{-# INLINE fromIArray #-}+fromIArray+ :: (IxShapeRepr (EltRepr ix) ~ EltRepr sh, IArray a e, IArray.Ix ix, Shape sh, Elt ix, Elt e)+ => a ix e+ -> Array sh e+fromIArray iarr = fromFunction sh (\ix -> iarr IArray.! fromIxShapeRepr (offset lo' ix))+ where+ (lo,hi) = IArray.bounds iarr+ lo' = toIxShapeRepr lo+ hi' = toIxShapeRepr hi+ sh = rangeToShape (lo', hi')++ -- IArray does not necessarily start indexing from zero. Thus, we need to+ -- add some offset to the Accelerate indices to map them onto the valid+ -- index range of the IArray+ --+ offset :: forall sh. Shape sh => sh -> sh -> sh+ offset ix0 ix = toElt $ go (eltType (undefined::sh)) (fromElt ix0) (fromElt ix)+ where+ go :: TupleType ix -> ix -> ix -> ix+ go TypeRunit () () = ()+ go (TypeRpair tl tr) (l0, r0) (l,r) = (go tl l0 l, go tr r0 r)+ go (TypeRscalar (SingleScalarType (NumSingleType (IntegralNumType TypeInt{})))) i0 i = i0+i+ go _ _ _ =+ $internalError "fromIArray" "error in index offset"+++-- | /O(n)/. Convert an Accelerate 'Array' to an 'IArray'.+--+-- See 'fromIArray' for a discussion on the expected shape types.+--+{-# INLINE toIArray #-}+toIArray+ :: forall ix sh a e. (IxShapeRepr (EltRepr ix) ~ EltRepr sh, IArray a e, IArray.Ix ix, Shape sh, Elt ix)+ => Maybe ix -- ^ if 'Just' this as the index lower bound, otherwise the array is indexed from zero+ -> Array sh e+ -> a ix e+toIArray mix0 arr = IArray.array bnds0 [(offset ix, arr ! toIxShapeRepr ix) | ix <- IArray.range bnds]+ where+ (u,v) = shapeToRange (shape arr)+ bnds@(lo,hi) = (fromIxShapeRepr u, fromIxShapeRepr v)+ bnds0 = (offset lo, offset hi)++ offset :: ix -> ix+ offset ix =+ case mix0 of+ Nothing -> ix+ Just ix0 -> offset' ix0 ix++ offset' :: ix -> ix -> ix+ offset' ix0 ix+ = fromIxShapeRepr+ . (toElt :: EltRepr sh -> sh)+ $ go (eltType (undefined::sh)) (fromElt (toIxShapeRepr ix0 :: sh)) (fromElt (toIxShapeRepr ix :: sh))+ where+ go :: TupleType sh' -> sh' -> sh' -> sh'+ go TypeRunit () () = ()+ go (TypeRpair tl tr) (l0,r0) (l,r) = (go tl l0 l, go tr r0 r)+ go (TypeRscalar (SingleScalarType (NumSingleType (IntegralNumType TypeInt{})))) i0 i = i0+i+ go _ _ _ =+ $internalError "toIArray" "error in index offset"+
+ src/Data/Array/Accelerate/IO/Data/Array/Internal.hs view
@@ -0,0 +1,46 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}+-- |+-- Module : Data.Array.Accelerate.IO.Data.Array.Internal+-- Copyright : [2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--++module Data.Array.Accelerate.IO.Data.Array.Internal+ where++import Data.Array.Accelerate.Array.Sugar+import Data.Array.Accelerate.Error+import Data.Array.Accelerate.Type+++type family IxShapeRepr e where+ IxShapeRepr () = ()+ IxShapeRepr Int = ((),Int)+ IxShapeRepr (t,h) = (IxShapeRepr t, h)++fromIxShapeRepr :: forall ix sh. (IxShapeRepr (EltRepr ix) ~ EltRepr sh, Shape sh, Elt ix) => sh -> ix+fromIxShapeRepr sh = toElt (go (eltType (undefined::ix)) (fromElt sh))+ where+ go :: forall ix'. TupleType ix' -> IxShapeRepr ix' -> ix'+ go TypeRunit () = ()+ go (TypeRpair tt _) (t, h) = (go tt t, h)+ go (TypeRscalar (SingleScalarType (NumSingleType (IntegralNumType TypeInt{})))) ((),h) = h+ go _ _ =+ $internalError "fromIxShapeRepr" "not a valid IArray.Ix"++toIxShapeRepr :: forall ix sh. (IxShapeRepr (EltRepr ix) ~ EltRepr sh, Shape sh, Elt ix) => ix -> sh+toIxShapeRepr ix = toElt (go (eltType (undefined::ix)) (fromElt ix))+ where+ go :: forall ix'. TupleType ix' -> ix' -> IxShapeRepr ix'+ go TypeRunit () = ()+ go (TypeRpair tt _) (t, h) = (go tt t, h)+ go (TypeRscalar (SingleScalarType (NumSingleType (IntegralNumType TypeInt{})))) h = ((),h)+ go _ _ =+ $internalError "toIxShapeRepr" "not a valid IArray.Ix"+
+ src/Data/Array/Accelerate/IO/Data/Array/Unboxed.hs view
@@ -0,0 +1,148 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}+-- |+-- Module : Data.Array.Accelerate.IO.Data.Array.Unboxed+-- Copyright : [2016..2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--+-- Efficient conversion between immutable unboxed 'IArray's and Accelerate+-- 'Array's.+--++module Data.Array.Accelerate.IO.Data.Array.Unboxed (++ IxShapeRepr,+ fromUArray,+ toUArray,++) where++import Data.Array.Accelerate.Array.Data+import Data.Array.Accelerate.Array.Sugar+import Data.Array.Accelerate.Array.Unique+import Data.Array.Accelerate.Error+import Data.Array.Accelerate.Lifetime+import Data.Array.Accelerate.Type+import qualified Data.Array.Accelerate.Array.Representation as R++import Data.Array.Accelerate.IO.Data.Array.Internal+import Data.Array.Accelerate.IO.Data.Vector.Primitive.Internal++import Data.Primitive ( Prim, sizeOf )+import Data.Primitive.ByteArray++import Data.Array.Base+import Data.Array.Unboxed as U hiding ( Array )+import System.IO.Unsafe+++-- | /O(n)/. Convert an unboxed 'UArray' into an Accelerate array.+--+-- See 'Data.Array.Accelerate.IO.Data.Array.IArray.fromIArray' for more+-- information about the array index type.+--+-- If the underlying vectors are pinned then this can be done without copying.+--+-- See also: <https://ghc.haskell.org/trac/ghc/ticket/5556>+--+-- @since 1.1.0.0@+--+{-# INLINE fromUArray #-}+fromUArray+ :: forall ix sh e. (IxShapeRepr (EltRepr ix) ~ EltRepr sh, IArray UArray e, Ix ix, Shape sh, Elt ix, Elt e)+ => UArray ix e+ -> Array sh e+fromUArray (UArray lo hi n ba#) = Array (fromElt sh) (aux (arrayElt :: ArrayEltR (EltRepr e)))+ where+ sh = rangeToShape (toIxShapeRepr lo, toIxShapeRepr hi) :: sh++ wrap :: forall a. Prim a => (UniqueArray a -> ArrayData a) -> ArrayData a+ wrap k = k $ unsafePerformIO (newUniqueArray =<< foreignPtrOfByteArray 0 (n * sizeOf (undefined::a)) (ByteArray ba#))++ aux :: ArrayEltR a -> ArrayData a+ aux ArrayEltRint = wrap AD_Int+ aux ArrayEltRint8 = wrap AD_Int8+ aux ArrayEltRint16 = wrap AD_Int16+ aux ArrayEltRint32 = wrap AD_Int32+ aux ArrayEltRint64 = wrap AD_Int64+ aux ArrayEltRword = wrap AD_Word+ aux ArrayEltRword8 = wrap AD_Word8+ aux ArrayEltRword16 = wrap AD_Word16+ aux ArrayEltRword32 = wrap AD_Word32+ aux ArrayEltRword64 = wrap AD_Word64+ aux ArrayEltRfloat = wrap AD_Float+ aux ArrayEltRdouble = wrap AD_Double+ aux ArrayEltRchar = wrap AD_Char+ aux ArrayEltRbool = $internalError "fromUArray" "TODO: Bool" -- need to unpack bit array+ aux _ = $internalError "fromUArray" "unsupported type"+++-- | /O(1)/ (typically). Convert an Accelerate 'Array' to an unboxed 'UArray'.+--+-- See 'Data.Array.Accelerate.IO.Data.Array.IArray.fromIArray' for more+-- information about the array index type.+--+-- If the array data was allocated by Accelerate, this can typically be done+-- without copying.+--+-- @since 1.1.0.0@+--+{-# INLINE toUArray #-}+toUArray+ :: forall ix sh e. (IxShapeRepr (EltRepr ix) ~ EltRepr sh, IArray UArray e, Ix ix, Shape sh, Elt ix)+ => Maybe ix -- ^ if 'Just' this is the index lower bound, otherwise the array is indexed from zero+ -> Array sh e+ -> UArray ix e+toUArray mix0 arr@(Array sh adata) =+ case ba of+ ByteArray ba# -> UArray lo hi n ba#+ where+ n = R.size sh+ bnds = shapeToRange (shape arr)+ lo = fromIxShapeRepr (offset (fst bnds))+ hi = fromIxShapeRepr (offset (snd bnds))+ ba = aux arrayElt adata++ offset :: sh -> sh+ offset ix =+ case mix0 of+ Nothing -> ix+ Just ix0 -> offset' ix0 ix++ offset' :: ix -> sh -> sh+ offset' ix0 = toElt . go (eltType (undefined::sh)) (fromElt (toIxShapeRepr ix0 :: sh)) . fromElt+ where+ go :: TupleType sh' -> sh' -> sh' -> sh'+ go TypeRunit () () = ()+ go (TypeRpair tl tr) (l0, r0) (l,r) = (go tl l0 l, go tr r0 r)+ go (TypeRscalar (SingleScalarType (NumSingleType (IntegralNumType TypeInt{})))) i0 i = i0+i+ go _ _ _ =+ $internalError "toUArray" "error in index offset"++ wrap :: forall a. Prim a => UniqueArray a -> ByteArray+ wrap ua = unsafePerformIO $ byteArrayOfForeignPtr (n * sizeOf (undefined::a)) (unsafeGetValue (uniqueArrayData ua))++ aux :: ArrayEltR a -> ArrayData a -> ByteArray+ aux ArrayEltRint (AD_Int v) = wrap v+ aux ArrayEltRint8 (AD_Int8 v) = wrap v+ aux ArrayEltRint16 (AD_Int16 v) = wrap v+ aux ArrayEltRint32 (AD_Int32 v) = wrap v+ aux ArrayEltRint64 (AD_Int64 v) = wrap v+ aux ArrayEltRword (AD_Word v) = wrap v+ aux ArrayEltRword8 (AD_Word8 v) = wrap v+ aux ArrayEltRword16 (AD_Word16 v) = wrap v+ aux ArrayEltRword32 (AD_Word32 v) = wrap v+ aux ArrayEltRword64 (AD_Word64 v) = wrap v+ aux ArrayEltRfloat (AD_Float v) = wrap v+ aux ArrayEltRdouble (AD_Double v) = wrap v+ aux ArrayEltRchar (AD_Char v) = wrap v+ aux ArrayEltRbool (AD_Bool _) = $internalError "toUArray" "TODO: Bool" -- need to pack bit array+ aux _ _ = $internalError "toUArray" "unsupported type"+
+ src/Data/Array/Accelerate/IO/Data/ByteString.hs view
@@ -0,0 +1,206 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE ViewPatterns #-}+-- |+-- Module : Data.Array.Accelerate.IO.Data.ByteString+-- Copyright : [2010..2011] Sean Seefried+-- [2010..2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--+-- Conversion between strict 'ByteString's and Accelerate 'Array's.+--++module Data.Array.Accelerate.IO.Data.ByteString (++ ByteStrings,+ fromByteStrings, toByteStrings,++) where++import Data.Array.Accelerate.Array.Data+import Data.Array.Accelerate.Array.Sugar+import Data.Array.Accelerate.Array.Unique+import Data.Array.Accelerate.Lifetime+import Data.Array.Accelerate.Type+import qualified Data.Array.Accelerate.Array.Representation as R++import Data.ByteString as B+import Data.ByteString.Internal as B+import Foreign.ForeignPtr+import Foreign.Storable+import System.IO.Unsafe++#if !MIN_VERSION_base(4,10,0)+import GHC.ForeignPtr+import GHC.Base+#endif+++-- | A family of types that represents a collection of 'ByteString's. The+-- structure of the collection depends on the element type @e@.+--+type family ByteStrings e++type instance ByteStrings () = ()+type instance ByteStrings Int = ByteString+type instance ByteStrings Int8 = ByteString+type instance ByteStrings Int16 = ByteString+type instance ByteStrings Int32 = ByteString+type instance ByteStrings Int64 = ByteString+type instance ByteStrings Word = ByteString+type instance ByteStrings Word8 = ByteString+type instance ByteStrings Word16 = ByteString+type instance ByteStrings Word32 = ByteString+type instance ByteStrings Word64 = ByteString+type instance ByteStrings CShort = ByteString+type instance ByteStrings CUShort = ByteString+type instance ByteStrings CInt = ByteString+type instance ByteStrings CUInt = ByteString+type instance ByteStrings CLong = ByteString+type instance ByteStrings CULong = ByteString+type instance ByteStrings CLLong = ByteString+type instance ByteStrings CULLong = ByteString+type instance ByteStrings CShort = ByteString+type instance ByteStrings Half = ByteString+type instance ByteStrings Float = ByteString+type instance ByteStrings Double = ByteString+type instance ByteStrings CFloat = ByteString+type instance ByteStrings CDouble = ByteString+type instance ByteStrings Bool = ByteString+type instance ByteStrings Char = ByteString+type instance ByteStrings CChar = ByteString+type instance ByteStrings CSChar = ByteString+type instance ByteStrings CUChar = ByteString+type instance ByteStrings (V2 a) = ByteStrings a+type instance ByteStrings (V3 a) = ByteStrings a+type instance ByteStrings (V4 a) = ByteStrings a+type instance ByteStrings (V8 a) = ByteStrings a+type instance ByteStrings (V16 a) = ByteStrings a+type instance ByteStrings (a,b) = (ByteStrings a, ByteStrings b)+++-- | /O(1)/. Treat a set of strict 'ByteStrings' as an Accelerate array. The+-- type of the elements @e@ in the output Accelerate array determines the+-- structure of the collection.+--+-- Data is considered to be in row-major order. You must ensure that each input+-- contains the right number of bytes (this is not checked).+--+-- The input data may not be modified through the 'ByteString's afterwards.+--+-- @since 1.1.0.0@+--+{-# INLINE fromByteStrings #-}+fromByteStrings :: (Shape sh, Elt e) => sh -> ByteStrings (EltRepr e) -> Array sh e+fromByteStrings sh bs = Array (fromElt sh) (aux arrayElt bs)+ where+ wrap :: (UniqueArray e -> r) -> ByteString -> r+ wrap k (B.toForeignPtr -> (ps,s,_)) =+ k (unsafePerformIO $ newUniqueArray (castForeignPtr (plusForeignPtr ps s)))++ aux :: ArrayEltR e -> ByteStrings e -> ArrayData e+ aux ArrayEltRunit = const AD_Unit+ aux ArrayEltRint = wrap AD_Int+ aux ArrayEltRint8 = wrap AD_Int8+ aux ArrayEltRint16 = wrap AD_Int16+ aux ArrayEltRint32 = wrap AD_Int32+ aux ArrayEltRint64 = wrap AD_Int64+ aux ArrayEltRword = wrap AD_Word+ aux ArrayEltRword8 = wrap AD_Word8+ aux ArrayEltRword16 = wrap AD_Word16+ aux ArrayEltRword32 = wrap AD_Word32+ aux ArrayEltRword64 = wrap AD_Word64+ aux ArrayEltRcshort = wrap AD_CShort+ aux ArrayEltRcushort = wrap AD_CUShort+ aux ArrayEltRcint = wrap AD_CInt+ aux ArrayEltRcuint = wrap AD_CUInt+ aux ArrayEltRclong = wrap AD_CLong+ aux ArrayEltRculong = wrap AD_CULong+ aux ArrayEltRcllong = wrap AD_CLLong+ aux ArrayEltRcullong = wrap AD_CULLong+ aux ArrayEltRhalf = wrap AD_Half+ aux ArrayEltRfloat = wrap AD_Float+ aux ArrayEltRdouble = wrap AD_Double+ aux ArrayEltRcfloat = wrap AD_CFloat+ aux ArrayEltRcdouble = wrap AD_CDouble+ aux ArrayEltRbool = wrap AD_Bool+ aux ArrayEltRchar = wrap AD_Char+ aux ArrayEltRcchar = wrap AD_CChar+ aux ArrayEltRcschar = wrap AD_CSChar+ aux ArrayEltRcuchar = wrap AD_CUChar+ aux (ArrayEltRvec2 ae) = AD_V2 . aux ae+ aux (ArrayEltRvec3 ae) = AD_V3 . aux ae+ aux (ArrayEltRvec4 ae) = AD_V4 . aux ae+ aux (ArrayEltRvec8 ae) = AD_V8 . aux ae+ aux (ArrayEltRvec16 ae) = AD_V16 . aux ae+ aux (ArrayEltRpair ae1 ae2) = \(v1,v2) -> AD_Pair (aux ae1 v1) (aux ae2 v2)+++-- | /O(1)/. Convert an Accelerate 'Array' into a collection of strict+-- 'ByteStrings'. The element type @e@ will determine the structure of the+-- output collection.+--+-- Data is considered to be in row-major order.+--+-- @since 1.1.0.0@+--+{-# INLINE toByteStrings #-}+toByteStrings :: (Shape sh, Elt e) => Array sh e -> ByteStrings (EltRepr e)+toByteStrings (Array sh adata) = aux arrayElt adata+ where+ n :: Int+ n = R.size sh++ wrap :: forall a. Storable a => UniqueArray a -> ByteString+ wrap (unsafeGetValue . uniqueArrayData -> fp) =+ B.fromForeignPtr (castForeignPtr fp) 0 (n * sizeOf (undefined::a))++ aux :: ArrayEltR e -> ArrayData e -> ByteStrings e+ aux ArrayEltRunit AD_Unit = ()+ aux ArrayEltRint (AD_Int s) = wrap s+ aux ArrayEltRint8 (AD_Int8 s) = wrap s+ aux ArrayEltRint16 (AD_Int16 s) = wrap s+ aux ArrayEltRint32 (AD_Int32 s) = wrap s+ aux ArrayEltRint64 (AD_Int64 s) = wrap s+ aux ArrayEltRword (AD_Word s) = wrap s+ aux ArrayEltRword8 (AD_Word8 s) = wrap s+ aux ArrayEltRword16 (AD_Word16 s) = wrap s+ aux ArrayEltRword32 (AD_Word32 s) = wrap s+ aux ArrayEltRword64 (AD_Word64 s) = wrap s+ aux ArrayEltRcshort (AD_CShort s) = wrap s+ aux ArrayEltRcushort (AD_CUShort s) = wrap s+ aux ArrayEltRcint (AD_CInt s) = wrap s+ aux ArrayEltRcuint (AD_CUInt s) = wrap s+ aux ArrayEltRclong (AD_CLong s) = wrap s+ aux ArrayEltRculong (AD_CULong s) = wrap s+ aux ArrayEltRcllong (AD_CLLong s) = wrap s+ aux ArrayEltRcullong (AD_CULLong s) = wrap s+ aux ArrayEltRhalf (AD_Half s) = wrap s+ aux ArrayEltRfloat (AD_Float s) = wrap s+ aux ArrayEltRdouble (AD_Double s) = wrap s+ aux ArrayEltRcfloat (AD_CFloat s) = wrap s+ aux ArrayEltRcdouble (AD_CDouble s) = wrap s+ aux ArrayEltRbool (AD_Bool s) = wrap s+ aux ArrayEltRchar (AD_Char s) = wrap s+ aux ArrayEltRcchar (AD_CChar s) = wrap s+ aux ArrayEltRcschar (AD_CSChar s) = wrap s+ aux ArrayEltRcuchar (AD_CUChar s) = wrap s+ aux (ArrayEltRvec2 ae) (AD_V2 s) = aux ae s+ aux (ArrayEltRvec3 ae) (AD_V3 s) = aux ae s+ aux (ArrayEltRvec4 ae) (AD_V4 s) = aux ae s+ aux (ArrayEltRvec8 ae) (AD_V8 s) = aux ae s+ aux (ArrayEltRvec16 ae) (AD_V16 s) = aux ae s+ aux (ArrayEltRpair ae1 ae2) (AD_Pair s1 s2) = (aux ae1 s1, aux ae2 s2)+++#if !MIN_VERSION_base(4,10,0)+plusForeignPtr :: ForeignPtr a -> Int -> ForeignPtr b+plusForeignPtr (ForeignPtr addr# c) (I# d#) = ForeignPtr (plusAddr# addr# d#) c+#endif+
+ src/Data/Array/Accelerate/IO/Data/Vector/Generic.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+-- |+-- Module : Data.Array.Accelerate.IO.Data.Vector.Generic+-- Copyright : [2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--+-- This module provides an instance for 'Data.Vector.Generic.Vector', for+-- immutable vectors from the @vector@ package backed by Accelerate arrays.+--+-- This allows computations written with the @vector@ library to read from and+-- store into, arrays which can then be passed directly to an Accelerate+-- computation.+--+-- @since 1.2.0.0+--++module Data.Array.Accelerate.IO.Data.Vector.Generic+ where++import Data.Array.Accelerate.Array.Sugar as A+import Data.Array.Accelerate.Array.Data as A+import Data.Array.Accelerate.IO.Data.Vector.Generic.Mutable as A++import qualified Data.Vector.Generic as V+import qualified Data.Vector.Generic.Mutable as M+++type instance V.Mutable Vector = MVector++instance Elt e => V.Vector Vector e where+ {-# INLINE basicUnsafeFreeze #-}+ {-# INLINE basicUnsafeThaw #-}+ {-# INLINE basicLength #-}+ {-# INLINE basicUnsafeSlice #-}+ {-# INLINE basicUnsafeIndexM #-}+ {-# INLINE basicUnsafeCopy #-}+ basicUnsafeFreeze (MArray sh mad) = return (Array sh mad)+ basicUnsafeThaw (Array sh ad) = return (MArray sh ad)+ basicLength (Array ((),n) _) = n++ basicUnsafeSlice i n (Array sh ad) =+ case M.basicUnsafeSlice i n (MArray sh ad :: MVector s e) of+ MArray sh' mad' -> Array sh' mad'++ basicUnsafeIndexM (Array _ ad) i = return $ toElt (unsafeIndexArrayData ad i)++ basicUnsafeCopy dst (Array sh ad) = M.basicUnsafeCopy dst (MArray sh ad)+
+ src/Data/Array/Accelerate/IO/Data/Vector/Generic/Mutable.hs view
@@ -0,0 +1,263 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE TypeSynonymInstances #-}+-- |+-- Module : Data.Array.Accelerate.IO.Data.Vector.Generic.Mutable+-- Copyright : [2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--+-- This module provides instance for 'Data.Vector.Generic.Mutable.MVector', for+-- generic mutable vectors backed by Accelerate.+--+-- @since 1.2.0.0+--++module Data.Array.Accelerate.IO.Data.Vector.Generic.Mutable+ where++import Data.Array.Accelerate.Array.Data as A+import Data.Array.Accelerate.Array.Sugar as A+import Data.Array.Accelerate.Array.Unique as A+import Data.Array.Accelerate.Lifetime++import qualified Data.Vector.Generic.Mutable as V++import Control.Monad.Primitive+import Data.Typeable+import Foreign.Ptr+import Foreign.Marshal.Utils+import Foreign.Storable+import Prelude hiding ( length )++import GHC.Base+import GHC.ForeignPtr+++-- | Dense, regular, mutable, multi-dimensional arrays+--+data MArray sh s e where+ MArray :: (Shape sh, Elt e)+ => EltRepr sh -- extent of dimensions == shape+ -> MutableArrayData (EltRepr e) -- mutable array payload+ -> MArray sh s e++deriving instance Typeable MArray++type MVector = MArray DIM1++instance Elt e => V.MVector MVector e where+ {-# INLINE basicLength #-}+ {-# INLINE basicUnsafeSlice #-}+ {-# INLINE basicOverlaps #-}+ {-# INLINE basicUnsafeNew #-}+ {-# INLINE basicInitialize #-}+ {-# INLINE basicUnsafeRead #-}+ {-# INLINE basicUnsafeWrite #-}+ {-# INLINE basicUnsafeCopy #-}+ basicLength (MArray ((), n) _) = n++ basicUnsafeSlice j m (MArray _ mad) = MArray ((),m) (go arrayElt mad 1)+ where+ go :: ArrayEltR a -> MutableArrayData a -> Int -> MutableArrayData a+ go ArrayEltRunit AD_Unit !_ = AD_Unit+ go ArrayEltRint (AD_Int v) !s = AD_Int (slice v s)+ go ArrayEltRint8 (AD_Int8 v) !s = AD_Int8 (slice v s)+ go ArrayEltRint16 (AD_Int16 v) !s = AD_Int16 (slice v s)+ go ArrayEltRint32 (AD_Int32 v) !s = AD_Int32 (slice v s)+ go ArrayEltRint64 (AD_Int64 v) !s = AD_Int64 (slice v s)+ go ArrayEltRword (AD_Word v) !s = AD_Word (slice v s)+ go ArrayEltRword8 (AD_Word8 v) !s = AD_Word8 (slice v s)+ go ArrayEltRword16 (AD_Word16 v) !s = AD_Word16 (slice v s)+ go ArrayEltRword32 (AD_Word32 v) !s = AD_Word32 (slice v s)+ go ArrayEltRword64 (AD_Word64 v) !s = AD_Word64 (slice v s)+ go ArrayEltRcshort (AD_CShort v) !s = AD_CShort (slice v s)+ go ArrayEltRcushort (AD_CUShort v) !s = AD_CUShort (slice v s)+ go ArrayEltRcint (AD_CInt v) !s = AD_CInt (slice v s)+ go ArrayEltRcuint (AD_CUInt v) !s = AD_CUInt (slice v s)+ go ArrayEltRclong (AD_CLong v) !s = AD_CLong (slice v s)+ go ArrayEltRculong (AD_CULong v) !s = AD_CULong (slice v s)+ go ArrayEltRcllong (AD_CLLong v) !s = AD_CLLong (slice v s)+ go ArrayEltRcullong (AD_CULLong v) !s = AD_CULLong (slice v s)+ go ArrayEltRhalf (AD_Half v) !s = AD_Half (slice v s)+ go ArrayEltRfloat (AD_Float v) !s = AD_Float (slice v s)+ go ArrayEltRdouble (AD_Double v) !s = AD_Double (slice v s)+ go ArrayEltRcfloat (AD_CFloat v) !s = AD_CFloat (slice v s)+ go ArrayEltRcdouble (AD_CDouble v) !s = AD_CDouble (slice v s)+ go ArrayEltRbool (AD_Bool v) !s = AD_Bool (slice v s)+ go ArrayEltRchar (AD_Char v) !s = AD_Char (slice v s)+ go ArrayEltRcchar (AD_CChar v) !s = AD_CChar (slice v s)+ go ArrayEltRcschar (AD_CSChar v) !s = AD_CSChar (slice v s)+ go ArrayEltRcuchar (AD_CUChar v) !s = AD_CUChar (slice v s)+ go (ArrayEltRvec2 ae) (AD_V2 v) !s = AD_V2 (go ae v (s*2))+ go (ArrayEltRvec3 ae) (AD_V3 v) !s = AD_V3 (go ae v (s*3))+ go (ArrayEltRvec4 ae) (AD_V4 v) !s = AD_V4 (go ae v (s*4))+ go (ArrayEltRvec8 ae) (AD_V8 v) !s = AD_V8 (go ae v (s*8))+ go (ArrayEltRvec16 ae) (AD_V16 v) !s = AD_V16 (go ae v (s*16))+ go (ArrayEltRpair ae1 ae2) (AD_Pair v1 v2) !s = AD_Pair (go ae1 v1 s) (go ae2 v2 s)++ slice :: forall a. Storable a => UniqueArray a -> Int -> UniqueArray a+ slice (UniqueArray uid (Lifetime lft w fp)) s =+ UniqueArray uid (Lifetime lft w (plusForeignPtr fp (j * s * sizeOf (undefined::a))))++ basicOverlaps (MArray ((),m) mad1) (MArray ((),n) mad2) = go arrayElt mad1 mad2 1+ where+ go :: ArrayEltR a -> MutableArrayData a -> MutableArrayData a -> Int -> Bool+ go ArrayEltRunit AD_Unit AD_Unit !_ = False+ go ArrayEltRint (AD_Int v1) (AD_Int v2) !s = overlaps v1 v2 s+ go ArrayEltRint8 (AD_Int8 v1) (AD_Int8 v2) !s = overlaps v1 v2 s+ go ArrayEltRint16 (AD_Int16 v1) (AD_Int16 v2) !s = overlaps v1 v2 s+ go ArrayEltRint32 (AD_Int32 v1) (AD_Int32 v2) !s = overlaps v1 v2 s+ go ArrayEltRint64 (AD_Int64 v1) (AD_Int64 v2) !s = overlaps v1 v2 s+ go ArrayEltRword (AD_Word v1) (AD_Word v2) !s = overlaps v1 v2 s+ go ArrayEltRword8 (AD_Word8 v1) (AD_Word8 v2) !s = overlaps v1 v2 s+ go ArrayEltRword16 (AD_Word16 v1) (AD_Word16 v2) !s = overlaps v1 v2 s+ go ArrayEltRword32 (AD_Word32 v1) (AD_Word32 v2) !s = overlaps v1 v2 s+ go ArrayEltRword64 (AD_Word64 v1) (AD_Word64 v2) !s = overlaps v1 v2 s+ go ArrayEltRcshort (AD_CShort v1) (AD_CShort v2) !s = overlaps v1 v2 s+ go ArrayEltRcushort (AD_CUShort v1) (AD_CUShort v2) !s = overlaps v1 v2 s+ go ArrayEltRcint (AD_CInt v1) (AD_CInt v2) !s = overlaps v1 v2 s+ go ArrayEltRcuint (AD_CUInt v1) (AD_CUInt v2) !s = overlaps v1 v2 s+ go ArrayEltRclong (AD_CLong v1) (AD_CLong v2) !s = overlaps v1 v2 s+ go ArrayEltRculong (AD_CULong v1) (AD_CULong v2) !s = overlaps v1 v2 s+ go ArrayEltRcllong (AD_CLLong v1) (AD_CLLong v2) !s = overlaps v1 v2 s+ go ArrayEltRcullong (AD_CULLong v1) (AD_CULLong v2) !s = overlaps v1 v2 s+ go ArrayEltRhalf (AD_Half v1) (AD_Half v2) !s = overlaps v1 v2 s+ go ArrayEltRfloat (AD_Float v1) (AD_Float v2) !s = overlaps v1 v2 s+ go ArrayEltRdouble (AD_Double v1) (AD_Double v2) !s = overlaps v1 v2 s+ go ArrayEltRcfloat (AD_CFloat v1) (AD_CFloat v2) !s = overlaps v1 v2 s+ go ArrayEltRcdouble (AD_CDouble v1) (AD_CDouble v2) !s = overlaps v1 v2 s+ go ArrayEltRbool (AD_Bool v1) (AD_Bool v2) !s = overlaps v1 v2 s+ go ArrayEltRchar (AD_Char v1) (AD_Char v2) !s = overlaps v1 v2 s+ go ArrayEltRcchar (AD_CChar v1) (AD_CChar v2) !s = overlaps v1 v2 s+ go ArrayEltRcschar (AD_CSChar v1) (AD_CSChar v2) !s = overlaps v1 v2 s+ go ArrayEltRcuchar (AD_CUChar v1) (AD_CUChar v2) !s = overlaps v1 v2 s+ go (ArrayEltRvec2 ae) (AD_V2 v1) (AD_V2 v2) !s = go ae v1 v2 (s*2)+ go (ArrayEltRvec3 ae) (AD_V3 v1) (AD_V3 v3) !s = go ae v1 v3 (s*3)+ go (ArrayEltRvec4 ae) (AD_V4 v1) (AD_V4 v4) !s = go ae v1 v4 (s*4)+ go (ArrayEltRvec8 ae) (AD_V8 v1) (AD_V8 v8) !s = go ae v1 v8 (s*8)+ go (ArrayEltRvec16 ae) (AD_V16 v1) (AD_V16 v16) !s = go ae v1 v16 (s*16)+ go (ArrayEltRpair ae1 ae2) (AD_Pair v11 v12) (AD_Pair v21 v22) !s = go ae1 v11 v21 s || go ae2 v12 v22 s++ overlaps :: forall a. Storable a => UniqueArray a -> UniqueArray a -> Int -> Bool+ overlaps (UniqueArray _ (Lifetime _ _ (ForeignPtr addr1# c1))) (UniqueArray _ (Lifetime _ _ (ForeignPtr addr2# c2))) s =+ let i = I# (addr2Int# addr1#)+ j = I# (addr2Int# addr2#)+ k = s * sizeOf (undefined::a)+ in+ same c1 c2 && (between i j (j + n*k) || between j i (i + m*k))++ same :: ForeignPtrContents -> ForeignPtrContents -> Bool+ same (PlainPtr mba1#) (PlainPtr mba2#) = isTrue# (sameMutableByteArray# mba1# mba2#)+ same (MallocPtr mba1# _) (MallocPtr mba2# _) = isTrue# (sameMutableByteArray# mba1# mba2#)+ -- same PlainForeignPtr{} PlainForeignPtr{} = False -- probably?+ same _ _ = False -- probably? should we still check whether the address ranges overlap?++ between :: Int -> Int -> Int -> Bool+ between x y z = x >= y && x < z++ basicUnsafeNew n = unsafePrimToPrim $ MArray ((),n) <$> newArrayData n++ basicInitialize (MArray ((),n) mad) = unsafePrimToPrim $ go (arrayElt :: ArrayEltR (EltRepr e)) (ptrsOfArrayData mad) 1+ where+ go :: ArrayEltR a -> ArrayPtrs a -> Int -> IO ()+ go ArrayEltRunit () !_ = return ()+ go ArrayEltRint p !s = initialise p s+ go ArrayEltRint8 p !s = initialise p s+ go ArrayEltRint16 p !s = initialise p s+ go ArrayEltRint32 p !s = initialise p s+ go ArrayEltRint64 p !s = initialise p s+ go ArrayEltRword p !s = initialise p s+ go ArrayEltRword8 p !s = initialise p s+ go ArrayEltRword16 p !s = initialise p s+ go ArrayEltRword32 p !s = initialise p s+ go ArrayEltRword64 p !s = initialise p s+ go ArrayEltRcshort p !s = initialise p s+ go ArrayEltRcushort p !s = initialise p s+ go ArrayEltRcint p !s = initialise p s+ go ArrayEltRcuint p !s = initialise p s+ go ArrayEltRclong p !s = initialise p s+ go ArrayEltRculong p !s = initialise p s+ go ArrayEltRcllong p !s = initialise p s+ go ArrayEltRcullong p !s = initialise p s+ go ArrayEltRhalf p !s = initialise p s+ go ArrayEltRfloat p !s = initialise p s+ go ArrayEltRdouble p !s = initialise p s+ go ArrayEltRcfloat p !s = initialise p s+ go ArrayEltRcdouble p !s = initialise p s+ go ArrayEltRbool p !s = initialise p s+ go ArrayEltRchar p !s = initialise p s+ go ArrayEltRcchar p !s = initialise p s+ go ArrayEltRcschar p !s = initialise p s+ go ArrayEltRcuchar p !s = initialise p s+ go (ArrayEltRvec2 ae) p !s = go ae p (s*2)+ go (ArrayEltRvec3 ae) p !s = go ae p (s*3)+ go (ArrayEltRvec4 ae) p !s = go ae p (s*4)+ go (ArrayEltRvec8 ae) p !s = go ae p (s*8)+ go (ArrayEltRvec16 ae) p !s = go ae p (s*16)+ go (ArrayEltRpair ae1 ae2) (p1,p2) s = go ae1 p1 s >> go ae2 p2 s++ initialise :: forall a. Storable a => Ptr a -> Int -> IO ()+ initialise p s = fillBytes p 0 (n * s * sizeOf (undefined::a))++ basicUnsafeRead (MArray _ mad) i = unsafePrimToPrim $ toElt <$> unsafeReadArrayData mad i+ basicUnsafeWrite (MArray _ mad) i v = unsafePrimToPrim $ unsafeWriteArrayData mad i (fromElt v)++ basicUnsafeCopy (MArray _ dst) (MArray ((),n) src) = unsafePrimToPrim $ go (arrayElt :: ArrayEltR (EltRepr e)) (ptrsOfArrayData dst) (ptrsOfArrayData src) 1+ where+ go :: ArrayEltR a -> ArrayPtrs a -> ArrayPtrs a -> Int -> IO ()+ go ArrayEltRunit () () !_ = return ()+ go ArrayEltRint u v !s = copy u v s+ go ArrayEltRint8 u v !s = copy u v s+ go ArrayEltRint16 u v !s = copy u v s+ go ArrayEltRint32 u v !s = copy u v s+ go ArrayEltRint64 u v !s = copy u v s+ go ArrayEltRword u v !s = copy u v s+ go ArrayEltRword8 u v !s = copy u v s+ go ArrayEltRword16 u v !s = copy u v s+ go ArrayEltRword32 u v !s = copy u v s+ go ArrayEltRword64 u v !s = copy u v s+ go ArrayEltRcshort u v !s = copy u v s+ go ArrayEltRcushort u v !s = copy u v s+ go ArrayEltRcint u v !s = copy u v s+ go ArrayEltRcuint u v !s = copy u v s+ go ArrayEltRclong u v !s = copy u v s+ go ArrayEltRculong u v !s = copy u v s+ go ArrayEltRcllong u v !s = copy u v s+ go ArrayEltRcullong u v !s = copy u v s+ go ArrayEltRhalf u v !s = copy u v s+ go ArrayEltRfloat u v !s = copy u v s+ go ArrayEltRdouble u v !s = copy u v s+ go ArrayEltRcfloat u v !s = copy u v s+ go ArrayEltRcdouble u v !s = copy u v s+ go ArrayEltRbool u v !s = copy u v s+ go ArrayEltRchar u v !s = copy u v s+ go ArrayEltRcchar u v !s = copy u v s+ go ArrayEltRcschar u v !s = copy u v s+ go ArrayEltRcuchar u v !s = copy u v s+ go (ArrayEltRvec2 ae) u v !s = go ae u v (s*2)+ go (ArrayEltRvec3 ae) u v !s = go ae u v (s*3)+ go (ArrayEltRvec4 ae) u v !s = go ae u v (s*4)+ go (ArrayEltRvec8 ae) u v !s = go ae u v (s*8)+ go (ArrayEltRvec16 ae) u v !s = go ae u v (s*16)+ go (ArrayEltRpair ae1 ae2) (u1,u2) (v1,v2) s = go ae1 u1 v1 s >> go ae2 u2 v2 s++ copy :: forall a. Storable a => Ptr a -> Ptr a -> Int -> IO ()+ copy u v s = copyBytes u v (n * s * sizeOf (undefined::a))+++#if !MIN_VERSION_base(4,10,0)+plusForeignPtr :: ForeignPtr a -> Int -> ForeignPtr b+plusForeignPtr (ForeignPtr addr# c) (I# i#) = ForeignPtr (plusAddr# addr# i#) c+#endif+
+ src/Data/Array/Accelerate/IO/Data/Vector/Primitive.hs view
@@ -0,0 +1,140 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}+-- |+-- Module : Data.Array.Accelerate.IO.Data.Vector.Primitive+-- Copyright : [2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--+-- Efficient conversion between 'Data.Vector.Primitive' vectors and Accelerate+-- 'Array's.+--++module Data.Array.Accelerate.IO.Data.Vector.Primitive (++ Vectors,+ toVectors,+ fromVectors,++) where++import Data.Vector.Primitive++import Data.Array.Accelerate.IO.Data.Vector.Primitive.Internal++import Data.Array.Accelerate.Array.Data+import Data.Array.Accelerate.Array.Sugar hiding ( Vector )+import Data.Array.Accelerate.Array.Unique+import Data.Array.Accelerate.Error+import qualified Data.Array.Accelerate.Array.Representation as R++import Data.Int+import Data.Word+++-- | A family of types which represent a collection of Primitive Vectors. The+-- structure of the collection depends on the element type @e@ of the+-- corresponding Accelerate array.+--+type family Vectors e :: *++type instance Vectors () = ()+type instance Vectors Int = Vector Int+type instance Vectors Int8 = Vector Int8+type instance Vectors Int16 = Vector Int16+type instance Vectors Int32 = Vector Int32+type instance Vectors Int64 = Vector Int64+type instance Vectors Word = Vector Word+type instance Vectors Word8 = Vector Word8+type instance Vectors Word16 = Vector Word16+type instance Vectors Word32 = Vector Word32+type instance Vectors Word64 = Vector Word64+type instance Vectors Float = Vector Float+type instance Vectors Double = Vector Double+type instance Vectors Char = Vector Char+type instance Vectors (a,b) = (Vectors a, Vectors b)+++-- | /O(n)/ (typically). Convert a collection of primitive vectors into an+-- Accelerate array.+--+-- If the underlying vectors are pinned then this can be done without.+--+-- See also: <https://ghc.haskell.org/trac/ghc/ticket/5556>+--+-- @since 1.1.0.0@+--+{-# INLINE fromVectors #-}+fromVectors :: (Shape sh, Elt e) => sh -> Vectors (EltRepr e) -> Array sh e+fromVectors sh vecs = Array (fromElt sh) (aux arrayElt vecs)+ where+ {-# INLINE wrap #-}+ wrap :: Prim a => Vector a -> UniqueArray a+ wrap v@(Vector _ l _)+ = $boundsCheck "fromVectors" "shape mismatch" (size sh == l)+ $ uniqueArrayOfVector v++ {-# INLINE aux #-}+ aux :: ArrayEltR e -> Vectors e -> ArrayData e+ aux ArrayEltRunit _ = AD_Unit+ aux ArrayEltRint v = AD_Int (wrap v)+ aux ArrayEltRint8 v = AD_Int8 (wrap v)+ aux ArrayEltRint16 v = AD_Int16 (wrap v)+ aux ArrayEltRint32 v = AD_Int32 (wrap v)+ aux ArrayEltRint64 v = AD_Int64 (wrap v)+ aux ArrayEltRword v = AD_Word (wrap v)+ aux ArrayEltRword8 v = AD_Word8 (wrap v)+ aux ArrayEltRword16 v = AD_Word16 (wrap v)+ aux ArrayEltRword32 v = AD_Word32 (wrap v)+ aux ArrayEltRword64 v = AD_Word64 (wrap v)+ aux ArrayEltRchar v = AD_Char (wrap v)+ aux ArrayEltRfloat v = AD_Float (wrap v)+ aux ArrayEltRdouble v = AD_Double (wrap v)+ aux (ArrayEltRpair ad1 ad2) (v1,v2) = AD_Pair (aux ad1 v1) (aux ad2 v2)+ --+ aux _ _ = $internalError "fromVectors" "unsupported type"+++-- | /O(1)/ (typically). Convert an Accelerate array into a collection of+-- primitive vectors.+--+-- If the array data was allocated by Accelerate, this can typically be done+-- without copying.+--+-- @since 1.1.0.0@+--+{-# INLINE toVectors #-}+toVectors :: (Shape sh, Elt e) => Array sh e -> Vectors (EltRepr e)+toVectors (Array sh adata) = aux arrayElt adata+ where+ n :: Int+ !n = R.size sh++ {-# INLINE wrap #-}+ wrap :: Prim a => UniqueArray a -> Vector a+ wrap ua = vectorOfUniqueArray n ua++ {-# INLINE aux #-}+ aux :: ArrayEltR e -> ArrayData e -> Vectors e+ aux ArrayEltRunit AD_Unit = ()+ aux ArrayEltRint (AD_Int v) = wrap v+ aux ArrayEltRint8 (AD_Int8 v) = wrap v+ aux ArrayEltRint16 (AD_Int16 v) = wrap v+ aux ArrayEltRint32 (AD_Int32 v) = wrap v+ aux ArrayEltRint64 (AD_Int64 v) = wrap v+ aux ArrayEltRword (AD_Word v) = wrap v+ aux ArrayEltRword8 (AD_Word8 v) = wrap v+ aux ArrayEltRword16 (AD_Word16 v) = wrap v+ aux ArrayEltRword32 (AD_Word32 v) = wrap v+ aux ArrayEltRword64 (AD_Word64 v) = wrap v+ aux ArrayEltRchar (AD_Char v) = wrap v+ aux ArrayEltRfloat (AD_Float v) = wrap v+ aux ArrayEltRdouble (AD_Double v) = wrap v+ aux (ArrayEltRpair ad1 ad2) (AD_Pair v1 v2) = (aux ad1 v1, aux ad2 v2)+ --+ aux _ _ = $internalError "toVectors" "unsupported type"+
+ src/Data/Array/Accelerate/IO/Data/Vector/Primitive/Internal.hs view
@@ -0,0 +1,82 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE UnboxedTuples #-}+-- |+-- Module : Data.Array.Accelerate.IO.Data.Vector.Primitive.Internal+-- Copyright : [2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--++module Data.Array.Accelerate.IO.Data.Vector.Primitive.Internal+ where++import Data.Primitive ( sizeOf )+import Data.Primitive.ByteArray++import Data.Vector.Primitive++import Data.Array.Accelerate.Array.Unique+import Data.Array.Accelerate.Lifetime++import GHC.Base+import GHC.ForeignPtr+import System.IO.Unsafe+++-- Convert a primitive vector into a unique array+--+{-# INLINE uniqueArrayOfVector #-}+uniqueArrayOfVector :: forall a. Prim a => Vector a -> UniqueArray a+uniqueArrayOfVector (Vector o l ba)+ = unsafePerformIO+ $ newUniqueArray =<< foreignPtrOfByteArray o (l * sizeOf (undefined::a)) ba++-- Convert a unique array into a primitive vector+--+{-# INLINE vectorOfUniqueArray #-}+vectorOfUniqueArray :: forall a. Prim a => Int -> UniqueArray a -> Vector a+vectorOfUniqueArray n ua+ = unsafePerformIO+ $ Vector 0 n `fmap` byteArrayOfForeignPtr (n * sizeOf (undefined::a)) (unsafeGetValue (uniqueArrayData ua))+++-- Return the ByteArray underlying a ForeignPtr, or a new byte array if it is+-- not a Plain ForeignPtr.+--+{-# INLINE byteArrayOfForeignPtr #-}+byteArrayOfForeignPtr :: Int -> ForeignPtr a -> IO ByteArray+byteArrayOfForeignPtr (I# bytes#) (ForeignPtr addr# c) = IO $ \s ->+ case c of+ PlainPtr mba# -> case unsafeFreezeByteArray# mba# s of+ (# s', ba# #) -> (# s', ByteArray ba# #)++ _ -> case newAlignedPinnedByteArray# bytes# 16# s of+ (# s1, mba# #) -> case copyAddrToByteArray# addr# mba# 0# bytes# s1 of+ s2 -> case unsafeFreezeByteArray# mba# s2 of+ (# s3, ba# #) -> (# s3, ByteArray ba# #)+++-- Return the ByteArray as a ForeignPtr. This will attempt a non-copying+-- conversion, if the underlying byte array is pinned.+--+{-# INLINE foreignPtrOfByteArray #-}+foreignPtrOfByteArray :: Int -> Int -> ByteArray -> IO (ForeignPtr a)+foreignPtrOfByteArray (I# soff#) (I# bytes#) (ByteArray ba#) = IO $ \s ->+ case isByteArrayPinned# ba# of+ 0# -> case newAlignedPinnedByteArray# bytes# 16# s of+ (# s1, mba# #) -> case copyByteArray# ba# 0# mba# soff# bytes# s1 of+ s2 -> (# s2, ForeignPtr (byteArrayContents# (unsafeCoerce# mba#)) (PlainPtr mba#) #)++ _ -> (# s, ForeignPtr (byteArrayContents# ba#) (PlainPtr (unsafeCoerce# ba#)) #)+++#if !MIN_VERSION_base(4,10,0)+isByteArrayPinned# :: ByteArray# -> Int#+isByteArrayPinned# _ = 0#+#endif+
+ src/Data/Array/Accelerate/IO/Data/Vector/Storable.hs view
@@ -0,0 +1,197 @@+{-# LANGUAGE GADTs #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}+-- |+-- Module : Data.Array.Accelerate.IO.Data.Vector.Storable+-- Copyright : [2012] Adam C. Foltzer+-- [2012..2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--+-- Efficient non-copying conversion between 'Data.Vector.Storable' vectors and+-- Accelerate 'Array's.+--++module Data.Array.Accelerate.IO.Data.Vector.Storable (++ Vectors,+ toVectors,+ fromVectors,++) where++-- friends+import Data.Array.Accelerate.Array.Data+import Data.Array.Accelerate.Array.Sugar hiding ( Vector )+import Data.Array.Accelerate.Array.Unique+import Data.Array.Accelerate.Error+import Data.Array.Accelerate.Lifetime+import Data.Array.Accelerate.Type+import qualified Data.Array.Accelerate.Array.Representation as R++-- standard libraries+import Data.Vector.Storable+import System.IO.Unsafe+++-- | A family of types that represents a collection of storable 'Vector's. The+-- structure of the collection depends on the element type @e@.+--+-- For example:+--+-- * if @e :: Int@, then @Vectors (EltRepr e) :: Vector Int@+--+-- * if @e :: (Double, Float)@, then @Vectors (EltRepr e) :: (((), Vector Double), Vector Float)@+--+type family Vectors e++type instance Vectors () = ()+type instance Vectors Int = Vector Int+type instance Vectors Int8 = Vector Int8+type instance Vectors Int16 = Vector Int16+type instance Vectors Int32 = Vector Int32+type instance Vectors Int64 = Vector Int64+type instance Vectors Word = Vector Word+type instance Vectors Word8 = Vector Word8+type instance Vectors Word16 = Vector Word16+type instance Vectors Word32 = Vector Word32+type instance Vectors Word64 = Vector Word64+type instance Vectors CShort = Vector Int16+type instance Vectors CUShort = Vector Word16+type instance Vectors CInt = Vector Int32+type instance Vectors CUInt = Vector Word32+type instance Vectors CLong = Vector HTYPE_LONG+type instance Vectors CULong = Vector HTYPE_UNSIGNED_LONG+type instance Vectors CLLong = Vector Int64+type instance Vectors CULLong = Vector Word64+type instance Vectors Half = Vector Half+type instance Vectors Float = Vector Float+type instance Vectors CFloat = Vector Float+type instance Vectors Double = Vector Double+type instance Vectors CDouble = Vector Double+type instance Vectors Bool = Vector Word8+type instance Vectors Char = Vector Char+type instance Vectors CChar = Vector HTYPE_CCHAR+type instance Vectors CSChar = Vector Int8+type instance Vectors CUChar = Vector Word8+type instance Vectors (V2 a) = Vectors a+type instance Vectors (V3 a) = Vectors a+type instance Vectors (V4 a) = Vectors a+type instance Vectors (V8 a) = Vectors a+type instance Vectors (V16 a) = Vectors a+type instance Vectors (a,b) = (Vectors a, Vectors b)+++-- | /O(1)/. Treat a set of storable vectors as Accelerate arrays. The type of+-- elements @e@ in the output Accelerate array determines the structure of the+-- collection that will be required as the second argument. See 'Vectors'.+--+-- Data will be consumed from the vector in row-major order. You must make sure+-- that each of the input vectors contains the right number of elements+--+{-# INLINE fromVectors #-}+fromVectors :: (Shape sh, Elt e) => sh -> Vectors (EltRepr e) -> Array sh e+fromVectors sh vecs = Array (fromElt sh) (aux arrayElt vecs 1)+ where+ {-# INLINE wrap #-}+ wrap :: Storable e => (UniqueArray e -> a) -> Vector e -> Int -> a+ wrap k v s+ = $boundsCheck "fromVectors" "shape mismatch" (vsize `quot` s == size sh)+ $ k (unsafePerformIO $ newUniqueArray fp)+ where+ (fp,vsize) = unsafeToForeignPtr0 v++ {-# INLINE aux #-}+ aux :: ArrayEltR e -> Vectors e -> Int -> ArrayData e+ aux ArrayEltRunit _ _ = AD_Unit+ aux ArrayEltRint v s = wrap AD_Int v s+ aux ArrayEltRint8 v s = wrap AD_Int8 v s+ aux ArrayEltRint16 v s = wrap AD_Int16 v s+ aux ArrayEltRint32 v s = wrap AD_Int32 v s+ aux ArrayEltRint64 v s = wrap AD_Int64 v s+ aux ArrayEltRword v s = wrap AD_Word v s+ aux ArrayEltRword8 v s = wrap AD_Word8 v s+ aux ArrayEltRword16 v s = wrap AD_Word16 v s+ aux ArrayEltRword32 v s = wrap AD_Word32 v s+ aux ArrayEltRword64 v s = wrap AD_Word64 v s+ aux ArrayEltRcshort v s = wrap AD_CShort v s+ aux ArrayEltRcushort v s = wrap AD_CUShort v s+ aux ArrayEltRcint v s = wrap AD_CInt v s+ aux ArrayEltRcuint v s = wrap AD_CUInt v s+ aux ArrayEltRclong v s = wrap AD_CLong v s+ aux ArrayEltRculong v s = wrap AD_CULong v s+ aux ArrayEltRcllong v s = wrap AD_CLLong v s+ aux ArrayEltRcullong v s = wrap AD_CULLong v s+ aux ArrayEltRhalf v s = wrap AD_Half v s+ aux ArrayEltRfloat v s = wrap AD_Float v s+ aux ArrayEltRdouble v s = wrap AD_Double v s+ aux ArrayEltRcfloat v s = wrap AD_CFloat v s+ aux ArrayEltRcdouble v s = wrap AD_CDouble v s+ aux ArrayEltRbool v s = wrap AD_Bool v s+ aux ArrayEltRchar v s = wrap AD_Char v s+ aux ArrayEltRcchar v s = wrap AD_CChar v s+ aux ArrayEltRcschar v s = wrap AD_CSChar v s+ aux ArrayEltRcuchar v s = wrap AD_CUChar v s+ aux (ArrayEltRvec2 ae) v s = AD_V2 (aux ae v (s*2))+ aux (ArrayEltRvec3 ae) v s = AD_V3 (aux ae v (s*3))+ aux (ArrayEltRvec4 ae) v s = AD_V4 (aux ae v (s*4))+ aux (ArrayEltRvec8 ae) v s = AD_V8 (aux ae v (s*8))+ aux (ArrayEltRvec16 ae) v s = AD_V16 (aux ae v (s*16))+ aux (ArrayEltRpair ae1 ae2) (v1,v2) s = AD_Pair (aux ae1 v1 s) (aux ae2 v2 s)+++-- | /O(1)/. Turn the Accelerate array into a collection of storable 'Vector's.+-- The element type of the array @e@ will determine the structure of the output+-- collection. See 'Vectors'.+--+-- Data will be output in row-major order.+--+{-# INLINE toVectors #-}+toVectors :: (Shape sh, Elt e) => Array sh e -> Vectors (EltRepr e)+toVectors (Array sh adata) = aux arrayElt adata 1+ where+ {-# INLINE wrap #-}+ wrap :: Storable a => UniqueArray a -> Int -> Vector a+ wrap ua k = unsafeFromForeignPtr0 (unsafeGetValue (uniqueArrayData ua)) (R.size sh * k)++ {-# INLINE aux #-}+ aux :: ArrayEltR e -> ArrayData e -> Int -> Vectors e+ aux ArrayEltRunit AD_Unit _ = ()+ aux ArrayEltRint (AD_Int s) k = wrap s k+ aux ArrayEltRint8 (AD_Int8 s) k = wrap s k+ aux ArrayEltRint16 (AD_Int16 s) k = wrap s k+ aux ArrayEltRint32 (AD_Int32 s) k = wrap s k+ aux ArrayEltRint64 (AD_Int64 s) k = wrap s k+ aux ArrayEltRword (AD_Word s) k = wrap s k+ aux ArrayEltRword8 (AD_Word8 s) k = wrap s k+ aux ArrayEltRword16 (AD_Word16 s) k = wrap s k+ aux ArrayEltRword32 (AD_Word32 s) k = wrap s k+ aux ArrayEltRword64 (AD_Word64 s) k = wrap s k+ aux ArrayEltRcshort (AD_CShort s) k = wrap s k+ aux ArrayEltRcushort (AD_CUShort s) k = wrap s k+ aux ArrayEltRcint (AD_CInt s) k = wrap s k+ aux ArrayEltRcuint (AD_CUInt s) k = wrap s k+ aux ArrayEltRclong (AD_CLong s) k = wrap s k+ aux ArrayEltRculong (AD_CULong s) k = wrap s k+ aux ArrayEltRcllong (AD_CLLong s) k = wrap s k+ aux ArrayEltRcullong (AD_CULLong s) k = wrap s k+ aux ArrayEltRhalf (AD_Half s) k = wrap s k+ aux ArrayEltRfloat (AD_Float s) k = wrap s k+ aux ArrayEltRdouble (AD_Double s) k = wrap s k+ aux ArrayEltRcfloat (AD_CFloat s) k = wrap s k+ aux ArrayEltRcdouble (AD_CDouble s) k = wrap s k+ aux ArrayEltRbool (AD_Bool s) k = wrap s k+ aux ArrayEltRchar (AD_Char s) k = wrap s k+ aux ArrayEltRcchar (AD_CChar s) k = wrap s k+ aux ArrayEltRcschar (AD_CSChar s) k = wrap s k+ aux ArrayEltRcuchar (AD_CUChar s) k = wrap s k+ aux (ArrayEltRvec2 ae) (AD_V2 s) k = aux ae s (k*2)+ aux (ArrayEltRvec3 ae) (AD_V3 s) k = aux ae s (k*3)+ aux (ArrayEltRvec4 ae) (AD_V4 s) k = aux ae s (k*4)+ aux (ArrayEltRvec8 ae) (AD_V8 s) k = aux ae s (k*8)+ aux (ArrayEltRvec16 ae) (AD_V16 s) k = aux ae s (k*16)+ aux (ArrayEltRpair ae1 ae2) (AD_Pair s1 s2) k = (aux ae1 s1 k, aux ae2 s2 k)+
+ src/Data/Array/Accelerate/IO/Data/Vector/Unboxed.hs view
@@ -0,0 +1,356 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+-- |+-- Module : Data.Array.Accelerate.IO.Data.Vector.Unboxed+-- Copyright : [2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--+-- Efficient conversion between 'Data.Vector.Unboxed' vectors and Accelerate+-- 'Array's.+--++module Data.Array.Accelerate.IO.Data.Vector.Unboxed (++ Unbox(..),+ toUnboxed,+ fromUnboxed,++) where++import Data.Vector.Unboxed.Base hiding ( Unbox )+import qualified Data.Vector.Unboxed as U++import Data.Array.Accelerate.IO.Data.Vector.Primitive.Internal++import Data.Array.Accelerate.Array.Data+import Data.Array.Accelerate.Array.Sugar as A hiding ( Vector )+import qualified Data.Array.Accelerate.Array.Representation as R++import Data.Int+import Data.Word+++-- | /O(n)/ (typically). Convert an Unboxed vector into an Accelerate array+-- Accelerate array.+--+-- If the underlying vectors are pinned then this can be done without copying.+--+-- See also: <https://ghc.haskell.org/trac/ghc/ticket/5556>+--+-- @since 1.1.0.0@+--+{-# INLINE fromUnboxed #-}+fromUnboxed :: Unbox e => Vector e -> Array DIM1 e+fromUnboxed v = Array ((), U.length v) (arrayDataOfUnboxed v)+++-- | /O(1)/ (typically). Convert an Accelerate array into an Unboxed vector.+--+-- If the array data was allocated by Accelerate, this can typically be done+-- without copying. The resulting vector will be pinned.+--+-- @since 1.1.0.0@+--+{-# INLINE toUnboxed #-}+toUnboxed :: (Shape sh, Unbox e) => Array sh e -> Vector e+toUnboxed (Array sh adata) = unboxedOfArrayData (R.size sh) adata+++-- Instances+-- ---------++class (U.Unbox e, A.Elt e) => Unbox e where+ arrayDataOfUnboxed :: U.Vector e -> ArrayData (EltRepr e)+ unboxedOfArrayData :: Int -> ArrayData (EltRepr e) -> U.Vector e++instance Unbox Int where+ {-# INLINE arrayDataOfUnboxed #-}+ {-# INLINE unboxedOfArrayData #-}+ arrayDataOfUnboxed (V_Int v) = AD_Int (uniqueArrayOfVector v)+ unboxedOfArrayData !n (AD_Int v) = V_Int (vectorOfUniqueArray n v)++instance Unbox Int8 where+ {-# INLINE arrayDataOfUnboxed #-}+ {-# INLINE unboxedOfArrayData #-}+ arrayDataOfUnboxed (V_Int8 v) = AD_Int8 (uniqueArrayOfVector v)+ unboxedOfArrayData !n (AD_Int8 v) = V_Int8 (vectorOfUniqueArray n v)++instance Unbox Int16 where+ {-# INLINE arrayDataOfUnboxed #-}+ {-# INLINE unboxedOfArrayData #-}+ arrayDataOfUnboxed (V_Int16 v) = AD_Int16 (uniqueArrayOfVector v)+ unboxedOfArrayData !n (AD_Int16 v) = V_Int16 (vectorOfUniqueArray n v)++instance Unbox Int32 where+ {-# INLINE arrayDataOfUnboxed #-}+ {-# INLINE unboxedOfArrayData #-}+ arrayDataOfUnboxed (V_Int32 v) = AD_Int32 (uniqueArrayOfVector v)+ unboxedOfArrayData !n (AD_Int32 v) = V_Int32 (vectorOfUniqueArray n v)++instance Unbox Int64 where+ {-# INLINE arrayDataOfUnboxed #-}+ {-# INLINE unboxedOfArrayData #-}+ arrayDataOfUnboxed (V_Int64 v) = AD_Int64 (uniqueArrayOfVector v)+ unboxedOfArrayData !n (AD_Int64 v) = V_Int64 (vectorOfUniqueArray n v)++instance Unbox Word where+ {-# INLINE arrayDataOfUnboxed #-}+ {-# INLINE unboxedOfArrayData #-}+ arrayDataOfUnboxed (V_Word v) = AD_Word (uniqueArrayOfVector v)+ unboxedOfArrayData !n (AD_Word v) = V_Word (vectorOfUniqueArray n v)++instance Unbox Word8 where+ {-# INLINE arrayDataOfUnboxed #-}+ {-# INLINE unboxedOfArrayData #-}+ arrayDataOfUnboxed (V_Word8 v) = AD_Word8 (uniqueArrayOfVector v)+ unboxedOfArrayData !n (AD_Word8 v) = V_Word8 (vectorOfUniqueArray n v)++instance Unbox Word16 where+ {-# INLINE arrayDataOfUnboxed #-}+ {-# INLINE unboxedOfArrayData #-}+ arrayDataOfUnboxed (V_Word16 v) = AD_Word16 (uniqueArrayOfVector v)+ unboxedOfArrayData !n (AD_Word16 v) = V_Word16 (vectorOfUniqueArray n v)++instance Unbox Word32 where+ {-# INLINE arrayDataOfUnboxed #-}+ {-# INLINE unboxedOfArrayData #-}+ arrayDataOfUnboxed (V_Word32 v) = AD_Word32 (uniqueArrayOfVector v)+ unboxedOfArrayData !n (AD_Word32 v) = V_Word32 (vectorOfUniqueArray n v)++instance Unbox Word64 where+ {-# INLINE arrayDataOfUnboxed #-}+ {-# INLINE unboxedOfArrayData #-}+ arrayDataOfUnboxed (V_Word64 v) = AD_Word64 (uniqueArrayOfVector v)+ unboxedOfArrayData !n (AD_Word64 v) = V_Word64 (vectorOfUniqueArray n v)++instance Unbox Float where+ {-# INLINE arrayDataOfUnboxed #-}+ {-# INLINE unboxedOfArrayData #-}+ arrayDataOfUnboxed (V_Float v) = AD_Float (uniqueArrayOfVector v)+ unboxedOfArrayData !n (AD_Float v) = V_Float (vectorOfUniqueArray n v)++instance Unbox Double where+ {-# INLINE arrayDataOfUnboxed #-}+ {-# INLINE unboxedOfArrayData #-}+ arrayDataOfUnboxed (V_Double v) = AD_Double (uniqueArrayOfVector v)+ unboxedOfArrayData !n (AD_Double v) = V_Double (vectorOfUniqueArray n v)++instance Unbox Char where+ {-# INLINE arrayDataOfUnboxed #-}+ {-# INLINE unboxedOfArrayData #-}+ arrayDataOfUnboxed (V_Char v) = AD_Char (uniqueArrayOfVector v)+ unboxedOfArrayData !n (AD_Char v) = V_Char (vectorOfUniqueArray n v)++instance Unbox Bool where+ {-# INLINE arrayDataOfUnboxed #-}+ {-# INLINE unboxedOfArrayData #-}+ arrayDataOfUnboxed (V_Bool v) = AD_Bool (uniqueArrayOfVector v)+ unboxedOfArrayData !n (AD_Bool v) = V_Bool (vectorOfUniqueArray n v)++instance Unbox () where+ {-# INLINE arrayDataOfUnboxed #-}+ {-# INLINE unboxedOfArrayData #-}+ arrayDataOfUnboxed V_Unit{} = AD_Unit+ unboxedOfArrayData !n AD_Unit = V_Unit n++instance (Unbox a, Unbox b) => Unbox (a, b) where+ {-# INLINE arrayDataOfUnboxed #-}+ arrayDataOfUnboxed (V_2 _ a b) =+ AD_Unit `AD_Pair` arrayDataOfUnboxed a+ `AD_Pair` arrayDataOfUnboxed b+ --+ {-# INLINE unboxedOfArrayData #-}+ unboxedOfArrayData !n (AD_Unit `AD_Pair` a `AD_Pair` b) =+ V_2 n (unboxedOfArrayData n a)+ (unboxedOfArrayData n b)++instance (Unbox a, Unbox b, Unbox c) => Unbox (a, b, c) where+ {-# INLINE arrayDataOfUnboxed #-}+ arrayDataOfUnboxed (V_3 _ a b c) =+ AD_Unit `AD_Pair` arrayDataOfUnboxed a+ `AD_Pair` arrayDataOfUnboxed b+ `AD_Pair` arrayDataOfUnboxed c+ --+ {-# INLINE unboxedOfArrayData #-}+ unboxedOfArrayData !n (AD_Unit `AD_Pair` a `AD_Pair` b `AD_Pair` c) =+ V_3 n (unboxedOfArrayData n a)+ (unboxedOfArrayData n b)+ (unboxedOfArrayData n c)++instance (Unbox a, Unbox b, Unbox c, Unbox d) => Unbox (a, b, c, d) where+ {-# INLINE arrayDataOfUnboxed #-}+ arrayDataOfUnboxed (V_4 _ a b c d) =+ AD_Unit `AD_Pair` arrayDataOfUnboxed a+ `AD_Pair` arrayDataOfUnboxed b+ `AD_Pair` arrayDataOfUnboxed c+ `AD_Pair` arrayDataOfUnboxed d+ --+ {-# INLINE unboxedOfArrayData #-}+ unboxedOfArrayData !n (AD_Unit `AD_Pair` a `AD_Pair` b `AD_Pair` c `AD_Pair` d) =+ V_4 n (unboxedOfArrayData n a)+ (unboxedOfArrayData n b)+ (unboxedOfArrayData n c)+ (unboxedOfArrayData n d)++instance (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e) => Unbox (a, b, c, d, e) where+ {-# INLINE arrayDataOfUnboxed #-}+ arrayDataOfUnboxed (V_5 _ a b c d e) =+ AD_Unit `AD_Pair` arrayDataOfUnboxed a+ `AD_Pair` arrayDataOfUnboxed b+ `AD_Pair` arrayDataOfUnboxed c+ `AD_Pair` arrayDataOfUnboxed d+ `AD_Pair` arrayDataOfUnboxed e+ --+ {-# INLINE unboxedOfArrayData #-}+ unboxedOfArrayData !n (AD_Unit `AD_Pair` a `AD_Pair` b `AD_Pair` c `AD_Pair` d `AD_Pair` e) =+ V_5 n (unboxedOfArrayData n a)+ (unboxedOfArrayData n b)+ (unboxedOfArrayData n c)+ (unboxedOfArrayData n d)+ (unboxedOfArrayData n e)++instance (Unbox a, Unbox b, Unbox c, Unbox d, Unbox e, Unbox f) => Unbox (a, b, c, d, e, f) where+ {-# INLINE arrayDataOfUnboxed #-}+ arrayDataOfUnboxed (V_6 _ a b c d e f) =+ AD_Unit `AD_Pair` arrayDataOfUnboxed a+ `AD_Pair` arrayDataOfUnboxed b+ `AD_Pair` arrayDataOfUnboxed c+ `AD_Pair` arrayDataOfUnboxed d+ `AD_Pair` arrayDataOfUnboxed e+ `AD_Pair` arrayDataOfUnboxed f+ --+ {-# INLINE unboxedOfArrayData #-}+ unboxedOfArrayData !n (AD_Unit `AD_Pair` a `AD_Pair` b `AD_Pair` c `AD_Pair` d `AD_Pair` e `AD_Pair` f) =+ V_6 n (unboxedOfArrayData n a)+ (unboxedOfArrayData n b)+ (unboxedOfArrayData n c)+ (unboxedOfArrayData n d)+ (unboxedOfArrayData n e)+ (unboxedOfArrayData n f)++{--+#if MIN_VERSION_vector(0,12,0)+instance Unbox a => Unbox (Complex a) where+#else+instance (RealFloat a, Unbox a) => Unbox (Complex a) where+#endif+ {-# INLINE arrayDataOfUnboxed #-}+ {-# INLINE unboxedOfArrayData #-}+ arrayDataOfUnboxed (V_Complex v2) = arrayDataOfUnboxed v2+ unboxedOfArrayData !n v2 = V_Complex (unboxedOfArrayData n v2)+--}+++{--+-- | A family of types which represent a collection of Primitive Vectors. The+-- structure of the collection depends on the element type @e@ of the+-- corresponding Accelerate array.+--+type family Vectors e :: *++type instance Vectors () = ()+type instance Vectors Int = Vector Int+type instance Vectors Int8 = Vector Int8+type instance Vectors Int16 = Vector Int16+type instance Vectors Int32 = Vector Int32+type instance Vectors Int64 = Vector Int64+type instance Vectors Word = Vector Word+type instance Vectors Word8 = Vector Word8+type instance Vectors Word16 = Vector Word16+type instance Vectors Word32 = Vector Word32+type instance Vectors Word64 = Vector Word64+type instance Vectors Float = Vector Float+type instance Vectors Double = Vector Double+type instance Vectors Char = Vector Char+type instance Vectors Bool = Vector Bool+type instance Vectors (a,b) = (Vectors a, Vectors b)+++-- | /O(n)/ (typically). Convert a collection of unboxed vectors into an+-- Accelerate array.+--+-- Remember that unboxed vectors can be zipped and unzipped in O(1), so creating+-- the required 'Vectors' structure is free.+--+-- If the underlying vectors are pinned then this can be done without copying.+--+-- @since 1.1.0.0@+--+fromVectors :: (Shape sh, Elt e) => sh -> Vectors (EltRepr e) -> Array sh e+fromVectors sh vecs = Array (fromElt sh) (aux arrayElt vecs)+ where+ wrap :: forall a. P.Prim a => P.Vector a -> UniqueArray a+ wrap v@(P.Vector _ l _)+ = $boundsCheck "fromVectors" "shape mismatch" (size sh == l)+ $ uniqueArrayOfVector v+ --+ aux :: ArrayEltR e -> Vectors e -> ArrayData e+ aux ArrayEltRunit () = AD_Unit+ aux ArrayEltRint (V_Int v) = AD_Int (wrap v)+ aux ArrayEltRint8 (V_Int8 v) = AD_Int8 (wrap v)+ aux ArrayEltRint16 (V_Int16 v) = AD_Int16 (wrap v)+ aux ArrayEltRint32 (V_Int32 v) = AD_Int32 (wrap v)+ aux ArrayEltRint64 (V_Int64 v) = AD_Int64 (wrap v)+ aux ArrayEltRword (V_Word v) = AD_Word (wrap v)+ aux ArrayEltRword8 (V_Word8 v) = AD_Word8 (wrap v)+ aux ArrayEltRword16 (V_Word16 v) = AD_Word16 (wrap v)+ aux ArrayEltRword32 (V_Word32 v) = AD_Word32 (wrap v)+ aux ArrayEltRword64 (V_Word64 v) = AD_Word64 (wrap v)+ aux ArrayEltRfloat (V_Float v) = AD_Float (wrap v)+ aux ArrayEltRdouble (V_Double v) = AD_Double (wrap v)+ aux ArrayEltRchar (V_Char v) = AD_Char (wrap v)+ aux ArrayEltRbool (V_Bool v) = AD_Bool (wrap v)+ aux (ArrayEltRpair ad1 ad2) (v1,v2) = AD_Pair (aux ad1 v1) (aux ad2 v2)+ --+ aux _ _ = $internalError "fromVectors" "unsupported type"+++-- | /O(1)/ (typically). Convert an Accelerate array into a collection of+-- unboxed vectors.+--+-- If the array data was allocated by Accelerate, this can typically be done+-- without copying.+--+-- Remember that unboxed vectors can be zipped and unzipped in O(1), so you can+-- convert the result of this function into a more natural unboxed tuple+-- representation for free.+--+-- @since 1.1.0.0@+--+toVectors :: (Shape sh, Elt e) => Array sh e -> Vectors (EltRepr e)+toVectors (Array sh adata) = aux arrayElt adata+ where+ n :: Int+ n = R.size sh++ wrap :: forall a. P.Prim a => UniqueArray a -> P.Vector a+ wrap ua = vectorOfUniqueArray n ua++ aux :: ArrayEltR e -> ArrayData e -> Vectors e+ aux ArrayEltRunit AD_Unit = ()+ aux ArrayEltRint (AD_Int v) = V_Int (wrap v)+ aux ArrayEltRint8 (AD_Int8 v) = V_Int8 (wrap v)+ aux ArrayEltRint16 (AD_Int16 v) = V_Int16 (wrap v)+ aux ArrayEltRint32 (AD_Int32 v) = V_Int32 (wrap v)+ aux ArrayEltRint64 (AD_Int64 v) = V_Int64 (wrap v)+ aux ArrayEltRword (AD_Word v) = V_Word (wrap v)+ aux ArrayEltRword8 (AD_Word8 v) = V_Word8 (wrap v)+ aux ArrayEltRword16 (AD_Word16 v) = V_Word16 (wrap v)+ aux ArrayEltRword32 (AD_Word32 v) = V_Word32 (wrap v)+ aux ArrayEltRword64 (AD_Word64 v) = V_Word64 (wrap v)+ aux ArrayEltRfloat (AD_Float v) = V_Float (wrap v)+ aux ArrayEltRdouble (AD_Double v) = V_Double (wrap v)+ aux ArrayEltRchar (AD_Char v) = V_Char (wrap v)+ aux ArrayEltRbool (AD_Bool v) = V_Bool (wrap v)+ aux (ArrayEltRpair ad1 ad2) (AD_Pair v1 v2) = (aux ad1 v1, aux ad2 v2)+ --+ aux _ _ = $internalError "toVectors" "unsupported type"+--}+
+ src/Data/Array/Accelerate/IO/Foreign/ForeignPtr.hs view
@@ -0,0 +1,175 @@+{-# LANGUAGE TypeFamilies #-}+-- |+-- Module : Data.Array.Accelerate.IO.Foreign.ForeignPtr+-- Copyright : [2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--++module Data.Array.Accelerate.IO.Foreign.ForeignPtr+ where++import Data.Array.Accelerate.Array.Data+import Data.Array.Accelerate.Array.Sugar+import Data.Array.Accelerate.Array.Unique+import Data.Array.Accelerate.Lifetime+import Data.Array.Accelerate.Type++import Foreign.ForeignPtr+import System.IO.Unsafe+++-- | A family of types which represent a collection of 'ForeignPtr's. The+-- structure of the collection depends on the element type @e@.+--+type family ForeignPtrs e++type instance ForeignPtrs () = ()+type instance ForeignPtrs Int = ForeignPtr Int+type instance ForeignPtrs Int8 = ForeignPtr Int8+type instance ForeignPtrs Int16 = ForeignPtr Int16+type instance ForeignPtrs Int32 = ForeignPtr Int32+type instance ForeignPtrs Int64 = ForeignPtr Int64+type instance ForeignPtrs Word = ForeignPtr Word+type instance ForeignPtrs Word8 = ForeignPtr Word8+type instance ForeignPtrs Word16 = ForeignPtr Word16+type instance ForeignPtrs Word32 = ForeignPtr Word32+type instance ForeignPtrs Word64 = ForeignPtr Word64+type instance ForeignPtrs CShort = ForeignPtr Int16+type instance ForeignPtrs CUShort = ForeignPtr Word16+type instance ForeignPtrs CInt = ForeignPtr Int32+type instance ForeignPtrs CUInt = ForeignPtr Word32+type instance ForeignPtrs CLong = ForeignPtr HTYPE_LONG+type instance ForeignPtrs CULong = ForeignPtr HTYPE_UNSIGNED_LONG+type instance ForeignPtrs CLLong = ForeignPtr Int64+type instance ForeignPtrs CULLong = ForeignPtr Word64+type instance ForeignPtrs Half = ForeignPtr Half+type instance ForeignPtrs Float = ForeignPtr Float+type instance ForeignPtrs Double = ForeignPtr Double+type instance ForeignPtrs CFloat = ForeignPtr Float+type instance ForeignPtrs CDouble = ForeignPtr Double+type instance ForeignPtrs Bool = ForeignPtr Word8+type instance ForeignPtrs Char = ForeignPtr Char+type instance ForeignPtrs CChar = ForeignPtr HTYPE_CCHAR+type instance ForeignPtrs CSChar = ForeignPtr Int8+type instance ForeignPtrs CUChar = ForeignPtr Word8+type instance ForeignPtrs (V2 a) = ForeignPtrs a+type instance ForeignPtrs (V3 a) = ForeignPtrs a+type instance ForeignPtrs (V4 a) = ForeignPtrs a+type instance ForeignPtrs (V8 a) = ForeignPtrs a+type instance ForeignPtrs (V16 a) = ForeignPtrs a+type instance ForeignPtrs (a,b) = (ForeignPtrs a, ForeignPtrs b)+++-- | /O(1)/. Treat the set of 'ForeignPtrs' as an Accelerate array. The type of+-- elements @e@ in the output Accelerate array determines the structure of the+-- collection.+--+-- Data is considered to be in row-major order. You must ensure that each of the+-- input pointers contains the right number of elements.+--+-- The data may not be modified through the 'ForeignPtr's afterwards.+--+-- You should make sure that the data is suitably aligned.+--+-- @since 1.1.0.0@+--+{-# INLINE fromForeignPtrs #-}+fromForeignPtrs :: (Shape sh, Elt e) => sh -> ForeignPtrs (EltRepr e) -> Array sh e+fromForeignPtrs sh fps = Array (fromElt sh) (aux arrayElt fps)+ where+ wrap :: (UniqueArray e -> r) -> ForeignPtr e -> r+ wrap k fp = k (unsafePerformIO $ newUniqueArray fp)++ aux :: ArrayEltR e -> ForeignPtrs e -> ArrayData e+ aux ArrayEltRunit = const AD_Unit+ aux ArrayEltRint = wrap AD_Int+ aux ArrayEltRint8 = wrap AD_Int8+ aux ArrayEltRint16 = wrap AD_Int16+ aux ArrayEltRint32 = wrap AD_Int32+ aux ArrayEltRint64 = wrap AD_Int64+ aux ArrayEltRword = wrap AD_Word+ aux ArrayEltRword8 = wrap AD_Word8+ aux ArrayEltRword16 = wrap AD_Word16+ aux ArrayEltRword32 = wrap AD_Word32+ aux ArrayEltRword64 = wrap AD_Word64+ aux ArrayEltRcshort = wrap AD_CShort+ aux ArrayEltRcushort = wrap AD_CUShort+ aux ArrayEltRcint = wrap AD_CInt+ aux ArrayEltRcuint = wrap AD_CUInt+ aux ArrayEltRclong = wrap AD_CLong+ aux ArrayEltRculong = wrap AD_CULong+ aux ArrayEltRcllong = wrap AD_CLLong+ aux ArrayEltRcullong = wrap AD_CULLong+ aux ArrayEltRhalf = wrap AD_Half+ aux ArrayEltRfloat = wrap AD_Float+ aux ArrayEltRdouble = wrap AD_Double+ aux ArrayEltRcfloat = wrap AD_CFloat+ aux ArrayEltRcdouble = wrap AD_CDouble+ aux ArrayEltRbool = wrap AD_Bool+ aux ArrayEltRchar = wrap AD_Char+ aux ArrayEltRcchar = wrap AD_CChar+ aux ArrayEltRcschar = wrap AD_CSChar+ aux ArrayEltRcuchar = wrap AD_CUChar+ aux (ArrayEltRvec2 ae) = AD_V2 . aux ae+ aux (ArrayEltRvec3 ae) = AD_V3 . aux ae+ aux (ArrayEltRvec4 ae) = AD_V4 . aux ae+ aux (ArrayEltRvec8 ae) = AD_V8 . aux ae+ aux (ArrayEltRvec16 ae) = AD_V16 . aux ae+ aux (ArrayEltRpair ae1 ae2) = \(v1,v2) -> AD_Pair (aux ae1 v1) (aux ae2 v2)+++-- | /O(1)/. Yield the 'ForeignPtr's underlying the given Accelerate 'Array'.+-- The element type @e@ will determine the structure of the output collection.+--+-- Data is considered to be in row-major order.+--+-- @since 1.1.0.0@+--+{-# LANGUAGE toForeignPts #-}+toForeignPtrs :: (Shape sh, Elt e) => Array sh e -> ForeignPtrs (EltRepr e)+toForeignPtrs (Array _ adata) = aux arrayElt adata+ where+ wrap :: UniqueArray a -> ForeignPtr a+ wrap ua = unsafeGetValue (uniqueArrayData ua)++ aux :: ArrayEltR e -> ArrayData e -> ForeignPtrs e+ aux ArrayEltRunit AD_Unit = ()+ aux ArrayEltRint (AD_Int s) = wrap s+ aux ArrayEltRint8 (AD_Int8 s) = wrap s+ aux ArrayEltRint16 (AD_Int16 s) = wrap s+ aux ArrayEltRint32 (AD_Int32 s) = wrap s+ aux ArrayEltRint64 (AD_Int64 s) = wrap s+ aux ArrayEltRword (AD_Word s) = wrap s+ aux ArrayEltRword8 (AD_Word8 s) = wrap s+ aux ArrayEltRword16 (AD_Word16 s) = wrap s+ aux ArrayEltRword32 (AD_Word32 s) = wrap s+ aux ArrayEltRword64 (AD_Word64 s) = wrap s+ aux ArrayEltRcshort (AD_CShort s) = wrap s+ aux ArrayEltRcushort (AD_CUShort s) = wrap s+ aux ArrayEltRcint (AD_CInt s) = wrap s+ aux ArrayEltRcuint (AD_CUInt s) = wrap s+ aux ArrayEltRclong (AD_CLong s) = wrap s+ aux ArrayEltRculong (AD_CULong s) = wrap s+ aux ArrayEltRcllong (AD_CLLong s) = wrap s+ aux ArrayEltRcullong (AD_CULLong s) = wrap s+ aux ArrayEltRhalf (AD_Half s) = wrap s+ aux ArrayEltRfloat (AD_Float s) = wrap s+ aux ArrayEltRdouble (AD_Double s) = wrap s+ aux ArrayEltRcfloat (AD_CFloat s) = wrap s+ aux ArrayEltRcdouble (AD_CDouble s) = wrap s+ aux ArrayEltRbool (AD_Bool s) = wrap s+ aux ArrayEltRchar (AD_Char s) = wrap s+ aux ArrayEltRcchar (AD_CChar s) = wrap s+ aux ArrayEltRcschar (AD_CSChar s) = wrap s+ aux ArrayEltRcuchar (AD_CUChar s) = wrap s+ aux (ArrayEltRvec2 ae) (AD_V2 s) = aux ae s+ aux (ArrayEltRvec3 ae) (AD_V3 s) = aux ae s+ aux (ArrayEltRvec4 ae) (AD_V4 s) = aux ae s+ aux (ArrayEltRvec8 ae) (AD_V8 s) = aux ae s+ aux (ArrayEltRvec16 ae) (AD_V16 s) = aux ae s+ aux (ArrayEltRpair ae1 ae2) (AD_Pair s1 s2) = (aux ae1 s1, aux ae2 s2)+
+ src/Data/Array/Accelerate/IO/Foreign/Ptr.hs view
@@ -0,0 +1,101 @@+{-# LANGUAGE TypeFamilies #-}+-- |+-- Module : Data.Array.Accelerate.IO.Foreign.Ptr+-- Copyright : [2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--++module Data.Array.Accelerate.IO.Foreign.Ptr+ where++import Data.Array.Accelerate.Array.Data+import Data.Array.Accelerate.Array.Sugar+import Data.Array.Accelerate.Array.Unique++import Foreign.Ptr+import Foreign.ForeignPtr+import System.IO.Unsafe+++-- | A family of types which represent a collection of 'Ptr's. The+-- structure of the collection depends on the element type @e@.+--+type Ptrs e = ArrayPtrs e+++-- | /O(1)/. Treat the set of 'Ptrs' as an Accelerate array. The type of+-- elements @e@ in the output Accelerate array determines the structure of the+-- collection.+--+-- Data is considered to be in row-major order. You must ensure that each of the+-- input pointers contains the right number of elements.+--+-- The data may not be modified through the 'Ptrs' afterwards.+--+-- You are responsible for ensuring that the data remains alive for the duration+-- of the Accelerate computation, and for freeing it afterwards.+--+-- You should make sure that the data is suitably aligned.+--+-- @since 1.1.0.0@+--+{-# INLINE fromPtrs #-}+fromPtrs :: (Shape sh, Elt e) => sh -> Ptrs (EltRepr e) -> Array sh e+fromPtrs sh ps = Array (fromElt sh) (aux arrayElt ps)+ where+ wrap :: (UniqueArray e -> r) -> Ptr e -> r+ wrap k p = k (unsafePerformIO $ newUniqueArray =<< newForeignPtr_ p)++ aux :: ArrayEltR e -> Ptrs e -> ArrayData e+ aux ArrayEltRunit = const AD_Unit+ aux ArrayEltRint = wrap AD_Int+ aux ArrayEltRint8 = wrap AD_Int8+ aux ArrayEltRint16 = wrap AD_Int16+ aux ArrayEltRint32 = wrap AD_Int32+ aux ArrayEltRint64 = wrap AD_Int64+ aux ArrayEltRword = wrap AD_Word+ aux ArrayEltRword8 = wrap AD_Word8+ aux ArrayEltRword16 = wrap AD_Word16+ aux ArrayEltRword32 = wrap AD_Word32+ aux ArrayEltRword64 = wrap AD_Word64+ aux ArrayEltRcshort = wrap AD_CShort+ aux ArrayEltRcushort = wrap AD_CUShort+ aux ArrayEltRcint = wrap AD_CInt+ aux ArrayEltRcuint = wrap AD_CUInt+ aux ArrayEltRclong = wrap AD_CLong+ aux ArrayEltRculong = wrap AD_CULong+ aux ArrayEltRcllong = wrap AD_CLLong+ aux ArrayEltRcullong = wrap AD_CULLong+ aux ArrayEltRhalf = wrap AD_Half+ aux ArrayEltRfloat = wrap AD_Float+ aux ArrayEltRdouble = wrap AD_Double+ aux ArrayEltRcfloat = wrap AD_CFloat+ aux ArrayEltRcdouble = wrap AD_CDouble+ aux ArrayEltRbool = wrap AD_Bool+ aux ArrayEltRchar = wrap AD_Char+ aux ArrayEltRcchar = wrap AD_CChar+ aux ArrayEltRcschar = wrap AD_CSChar+ aux ArrayEltRcuchar = wrap AD_CUChar+ aux (ArrayEltRvec2 ae) = AD_V2 . aux ae+ aux (ArrayEltRvec3 ae) = AD_V3 . aux ae+ aux (ArrayEltRvec4 ae) = AD_V4 . aux ae+ aux (ArrayEltRvec8 ae) = AD_V8 . aux ae+ aux (ArrayEltRvec16 ae) = AD_V16 . aux ae+ aux (ArrayEltRpair ae1 ae2) = \(v1,v2) -> AD_Pair (aux ae1 v1) (aux ae2 v2)+++-- | /O(1)/. Yield the underlying 'Ptrs' backing the given Accelerate array. The+-- element type @e@ will determine the structure of the output collection.+--+-- Data is considered to be in row-major order.+--+-- @since 1.1.0.0@+--+{-# INLINE toPtrs #-}+toPtrs :: (Shape sh, Elt e) => Array sh e -> Ptrs (EltRepr e)+toPtrs (Array _ adata) = ptrsOfArrayData adata+
+ src/Data/Array/Repa/Repr/Accelerate.hs view
@@ -0,0 +1,176 @@+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE ExplicitForAll #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+-- |+-- Module : Data.Array.Repa.Repr.Accelerate+-- Copyright : [2012..2014] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--+-- This provides an efficient non-copying Repa manifest array representation+-- that can be passed directly to Accelerate.+--+-- The standard rules for dealing with manifest Repa arrays apply:+--+-- * If you want to have Repa 'R.computeP' directly into an Accelerate array,+-- the source array must have a delayed representation.+--+-- * If you want to copy between manifest arrays, use 'R.copyP' instead.+--++module Data.Array.Repa.Repr.Accelerate (++ A, Shapes,++ fromRepa, toRepa,+ computeAccS, computeAccP++) where++import Control.Monad++import qualified Data.Array.Repa as R+import qualified Data.Array.Repa.Eval as R+import qualified Data.Array.Accelerate.Array.Data as A+import qualified Data.Array.Accelerate.Array.Sugar as A+++-- | Index conversion and equivalence statement between Repa and Accelerate+-- array shapes. That is, a n-dimensional Repa array will produce an+-- n-dimensional Accelerate array of the same extent, and vice-versa.+--+class (R.Shape r, A.Shape a) => Shapes r a | a -> r, r -> a where+ -- these are really equivalent representations, so unsafeCoerce would probably+ -- work, but bad programmers get no cookies.+ toR :: a -> r+ toA :: r -> a++instance Shapes R.Z A.Z where+ {-# INLINE toR #-}+ toR A.Z = R.Z+ {-# INLINE toA #-}+ toA R.Z = A.Z++instance Shapes sr sa => Shapes (sr R.:. Int) (sa A.:. Int) where+ {-# INLINE toR #-}+ toR (sa A.:. sz) = toR sa R.:. sz+ {-# INLINE toA #-}+ toA (sr R.:. sz) = toA sr A.:. sz+++-- | The representation tag for manifest arrays based on Data.Array.Accelerate.+--+-- The Accelerate array implementation is based on type families and picks an+-- efficient, unboxed representation for every element type. Moreover, these+-- arrays can be handed efficiently (without copying) to Accelerate programs+-- for further computation.+--+data A++-- Repr ------------------------------------------------------------------------++-- | Reading elements of the Accelerate array+--+instance A.Elt e => R.Source A e where+ data Array A sh e+ = AAccelerate !sh !(A.ArrayData (A.EltRepr e))++ {-# INLINE extent #-}+ extent (AAccelerate sh _)+ = sh++ {-# INLINE linearIndex #-}+ linearIndex (AAccelerate sh adata) ix+ | ix >= 0 && ix < R.size sh+ = A.toElt (adata `A.unsafeIndexArrayData` ix)++ | otherwise+ = error "Repa: accelerate array out of bounds"++ {-# INLINE unsafeLinearIndex #-}+ unsafeLinearIndex (AAccelerate _ adata) ix+ = A.toElt (adata `A.unsafeIndexArrayData` ix)++ {-# INLINE deepSeqArray #-}+ deepSeqArray (AAccelerate sh adata) x+ = sh `R.deepSeq` adata `seq` x+++-- | Filling Accelerate arrays+--+instance A.Elt e => R.Target A e where+ data MVec A e+ = MAVec (A.MutableArrayData (A.EltRepr e))++ {-# INLINE newMVec #-}+ newMVec n+ = MAVec `liftM` A.newArrayData n++ {-# INLINE unsafeWriteMVec #-}+ unsafeWriteMVec (MAVec mad) n e+ = A.unsafeWriteArrayData mad n (A.fromElt e)++ {-# INLINE unsafeFreezeMVec #-}+ unsafeFreezeMVec sh (MAVec mad)+ = do adata <- A.unsafeFreezeArrayData mad+ return $! AAccelerate sh adata++ {-# INLINE deepSeqMVec #-}+ deepSeqMVec (MAVec arr) x -- maybe?+ = arr `seq` x++ {-# INLINE touchMVec #-}+ touchMVec _ -- maybe?+ = return ()+++-- Conversions -----------------------------------------------------------------++-- | /O(1)/. Wrap an Accelerate array.+--+toRepa+ :: Shapes sh sh'+ => A.Array sh' e -> R.Array A sh e+{-# INLINE toRepa #-}+toRepa arr@(A.Array _ adata)+ = AAccelerate (toR (A.shape arr)) adata++-- | /O(1)/. Unpack to an Accelerate array.+--+fromRepa+ :: (Shapes sh sh', A.Elt e)+ => R.Array A sh e -> A.Array sh' e+{-# INLINE fromRepa #-}+fromRepa (AAccelerate sh adata)+ = A.Array (A.fromElt (toA sh)) adata+++-- Computations ----------------------------------------------------------------++-- | Sequential computation of array elements+--+computeAccS+ :: (R.Load r sh e, A.Elt e)+ => R.Array r sh e -> R.Array A sh e+{-# INLINE computeAccS #-}+computeAccS = R.computeS++-- | Parallel computation of array elements+--+computeAccP+ :: (R.Load r sh e, A.Elt e, Monad m)+ => R.Array r sh e+ -> m (R.Array A sh e)+{-# INLINE computeAccP #-}+computeAccP = R.computeP+
+ test/Test.hs view
@@ -0,0 +1,29 @@+-- |+-- Module : Test+-- Copyright : [2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--++module Test where++import Test.Tasty++import Test.Array.IArray+import Test.Array.Unboxed+import Test.Vector.Storable+import Test.Vector.Unboxed++main :: IO ()+main+ = defaultMain+ $ testGroup "IO"+ [ test_vector_unboxed+ , test_vector_storable+ , test_array_iarray+ , test_array_unboxed+ ]+
+ test/Test/Array/IArray.hs view
@@ -0,0 +1,148 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+-- |+-- Module : Test.Array.IArray+-- Copyright : [2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--++module Test.Array.IArray+ where++import Test.Util+import Test.Tasty+import Test.Tasty.Hedgehog++import Data.Array.Accelerate ( Shape, Elt )+import Data.Array.Accelerate.Array.Sugar ( EltRepr )+import Data.Array.Accelerate.IO.Data.Array.IArray as A+import qualified Data.Array.Accelerate as A++import Data.Array.IArray hiding ( array, indices, elems )+import qualified Data.Array.IArray as I++import Hedgehog+import qualified Hedgehog.Gen as Gen+import qualified Hedgehog.Range as Range++import Data.Proxy+import Prelude+++iarray :: (Ix ix, IArray a e) => Gen (ix,ix) -> Gen e -> Gen (a ix e)+iarray ix e = do+ (lo,hi) <- ix+ let n = rangeSize (lo,hi)+ indices = range (lo,hi)+ --+ elems <- Gen.list (Range.singleton n) e+ return $ I.array (lo,hi) (zip indices elems)+++test_i2a+ :: forall ix sh a e. (Ix ix, IArray a e, Elt ix, Shape sh, Elt e, Eq e, Show (a ix e), Eq (a ix e), IxShapeRepr (EltRepr ix) ~ EltRepr sh)+ => Proxy a+ -> Gen sh+ -> Gen (ix,ix)+ -> Gen e+ -> Property+test_i2a _ _ ix e =+ property $ do+ ia <- forAll (iarray ix e :: Gen (a ix e))+ let+ (lo,_) = bounds ia+ acc = fromIArray ia :: A.Array sh e+ ia' = toIArray (Just lo) acc+ --+ I.elems ia === A.toList acc -- elements convert correctly+ ia === ia' -- indices round-trip correctly++test_a2i+ :: forall ix sh a e. (Ix ix, IArray a e, Elt ix, Shape sh, Elt e, Eq e, Show (a ix e), Eq sh, Eq e, IxShapeRepr (EltRepr ix) ~ EltRepr sh)+ => Proxy a+ -> Gen sh+ -> Gen (ix,ix)+ -> Gen e+ -> Property+test_a2i _ dim _ e =+ property $ do+ sh <- forAll dim+ acc <- forAll (array sh e)+ --+ A.toList acc === I.elems (toIArray Nothing acc :: a ix e)+++test_array_iarray :: TestTree+test_array_iarray =+ testGroup "Data.Array.IArray"+ [ testGroup "iarray->accelerate"+ [ testGroup "DIM1"+ [ testProperty "Int" $ test_i2a (Proxy::Proxy I.Array) dim1 ix1 int+ , testProperty "Int8" $ test_i2a (Proxy::Proxy I.Array) dim1 ix1 i8+ , testProperty "Int16" $ test_i2a (Proxy::Proxy I.Array) dim1 ix1 i16+ , testProperty "Int32" $ test_i2a (Proxy::Proxy I.Array) dim1 ix1 i32+ , testProperty "Int64" $ test_i2a (Proxy::Proxy I.Array) dim1 ix1 i64+ , testProperty "Word" $ test_i2a (Proxy::Proxy I.Array) dim1 ix1 word+ , testProperty "Word8" $ test_i2a (Proxy::Proxy I.Array) dim1 ix1 w8+ , testProperty "Word16" $ test_i2a (Proxy::Proxy I.Array) dim1 ix1 w16+ , testProperty "Word32" $ test_i2a (Proxy::Proxy I.Array) dim1 ix1 w32+ , testProperty "Word64" $ test_i2a (Proxy::Proxy I.Array) dim1 ix1 w64+ , testProperty "Float" $ test_i2a (Proxy::Proxy I.Array) dim1 ix1 f32+ , testProperty "Double" $ test_i2a (Proxy::Proxy I.Array) dim1 ix1 f64+ , testProperty "Complex Float" $ test_i2a (Proxy::Proxy I.Array) dim1 ix1 (complex f32)+ ]+ , testGroup "DIM2"+ [ testProperty "Int" $ test_i2a (Proxy::Proxy I.Array) dim2 ix2 int+ , testProperty "Int8" $ test_i2a (Proxy::Proxy I.Array) dim2 ix2 i8+ , testProperty "Int16" $ test_i2a (Proxy::Proxy I.Array) dim2 ix2 i16+ , testProperty "Int32" $ test_i2a (Proxy::Proxy I.Array) dim2 ix2 i32+ , testProperty "Int64" $ test_i2a (Proxy::Proxy I.Array) dim2 ix2 i64+ , testProperty "Word" $ test_i2a (Proxy::Proxy I.Array) dim2 ix2 word+ , testProperty "Word8" $ test_i2a (Proxy::Proxy I.Array) dim2 ix2 w8+ , testProperty "Word16" $ test_i2a (Proxy::Proxy I.Array) dim2 ix2 w16+ , testProperty "Word32" $ test_i2a (Proxy::Proxy I.Array) dim2 ix2 w32+ , testProperty "Word64" $ test_i2a (Proxy::Proxy I.Array) dim2 ix2 w64+ , testProperty "Float" $ test_i2a (Proxy::Proxy I.Array) dim2 ix2 f32+ , testProperty "Double" $ test_i2a (Proxy::Proxy I.Array) dim2 ix2 f64+ , testProperty "Complex Float" $ test_i2a (Proxy::Proxy I.Array) dim2 ix2 (complex f32)+ ]+ ]+ , testGroup "accelerate->iarray"+ [ testGroup "DIM1"+ [ testProperty "Int" $ test_a2i (Proxy::Proxy I.Array) dim1 ix1 int+ , testProperty "Int8" $ test_a2i (Proxy::Proxy I.Array) dim1 ix1 i8+ , testProperty "Int16" $ test_a2i (Proxy::Proxy I.Array) dim1 ix1 i16+ , testProperty "Int32" $ test_a2i (Proxy::Proxy I.Array) dim1 ix1 i32+ , testProperty "Int64" $ test_a2i (Proxy::Proxy I.Array) dim1 ix1 i64+ , testProperty "Word" $ test_a2i (Proxy::Proxy I.Array) dim1 ix1 word+ , testProperty "Word8" $ test_a2i (Proxy::Proxy I.Array) dim1 ix1 w8+ , testProperty "Word16" $ test_a2i (Proxy::Proxy I.Array) dim1 ix1 w16+ , testProperty "Word32" $ test_a2i (Proxy::Proxy I.Array) dim1 ix1 w32+ , testProperty "Word64" $ test_a2i (Proxy::Proxy I.Array) dim1 ix1 w64+ , testProperty "Float" $ test_a2i (Proxy::Proxy I.Array) dim1 ix1 f32+ , testProperty "Double" $ test_a2i (Proxy::Proxy I.Array) dim1 ix1 f64+ , testProperty "Complex Float" $ test_a2i (Proxy::Proxy I.Array) dim1 ix1 (complex f32)+ ]+ , testGroup "DIM2"+ [ testProperty "Int" $ test_a2i (Proxy::Proxy I.Array) dim2 ix2 int+ , testProperty "Int8" $ test_a2i (Proxy::Proxy I.Array) dim2 ix2 i8+ , testProperty "Int16" $ test_a2i (Proxy::Proxy I.Array) dim2 ix2 i16+ , testProperty "Int32" $ test_a2i (Proxy::Proxy I.Array) dim2 ix2 i32+ , testProperty "Int64" $ test_a2i (Proxy::Proxy I.Array) dim2 ix2 i64+ , testProperty "Word" $ test_a2i (Proxy::Proxy I.Array) dim2 ix2 word+ , testProperty "Word8" $ test_a2i (Proxy::Proxy I.Array) dim2 ix2 w8+ , testProperty "Word16" $ test_a2i (Proxy::Proxy I.Array) dim2 ix2 w16+ , testProperty "Word32" $ test_a2i (Proxy::Proxy I.Array) dim2 ix2 w32+ , testProperty "Word64" $ test_a2i (Proxy::Proxy I.Array) dim2 ix2 w64+ , testProperty "Float" $ test_a2i (Proxy::Proxy I.Array) dim2 ix2 f32+ , testProperty "Double" $ test_a2i (Proxy::Proxy I.Array) dim2 ix2 f64+ , testProperty "Complex Float" $ test_a2i (Proxy::Proxy I.Array) dim2 ix2 (complex f32)+ ]+ ]+ ]+
+ test/Test/Array/Unboxed.hs view
@@ -0,0 +1,128 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+-- |+-- Module : Test.Array.Unboxed+-- Copyright : [2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--++module Test.Array.Unboxed+ where++import Test.Array.IArray++import Test.Util+import Test.Tasty+import Test.Tasty.Hedgehog++import Data.Array.Accelerate ( Shape, Elt )+import Data.Array.Accelerate.Array.Sugar ( EltRepr )+import Data.Array.Accelerate.IO.Data.Array.Unboxed as A+import qualified Data.Array.Accelerate as A++import Data.Array.Unboxed as U hiding ( array )++import Hedgehog+++test_u2a+ :: forall ix sh e. (Ix ix, IArray UArray e, Elt ix, Shape sh, Elt e, Eq e, Show (UArray ix e), Eq (UArray ix e), IxShapeRepr (EltRepr ix) ~ EltRepr sh)+ => Gen sh+ -> Gen (ix,ix)+ -> Gen e+ -> Property+test_u2a _ ix e =+ property $ do+ ua <- forAll (iarray ix e :: Gen (UArray ix e))+ let+ (lo,_) = bounds ua+ acc = fromUArray ua :: A.Array sh e+ ua' = toUArray (Just lo) acc+ --+ U.elems ua === A.toList acc -- elements convert correctly+ ua === ua' -- indices round-trip correctly++test_a2u+ :: forall ix sh e. (Ix ix, IArray UArray e, Elt ix, Shape sh, Elt e, Show (UArray ix e), Eq (UArray ix e), Eq sh, Eq e, IxShapeRepr (EltRepr ix) ~ EltRepr sh)+ => Gen sh+ -> Gen (ix,ix)+ -> Gen e+ -> Property+test_a2u dim _ e =+ property $ do+ sh <- forAll dim+ arr <- forAll (array sh e)+ --+ A.toList arr === U.elems (toUArray Nothing arr :: UArray ix e)+++test_array_unboxed :: TestTree+test_array_unboxed =+ testGroup "Data.Array.Unboxed"+ [ testGroup "uarray->accelerate"+ [ testGroup "DIM1"+ [ testProperty "Int" $ test_u2a dim1 ix1 int+ , testProperty "Int8" $ test_u2a dim1 ix1 i8+ , testProperty "Int16" $ test_u2a dim1 ix1 i16+ , testProperty "Int32" $ test_u2a dim1 ix1 i32+ , testProperty "Int64" $ test_u2a dim1 ix1 i64+ , testProperty "Word" $ test_u2a dim1 ix1 word+ , testProperty "Word8" $ test_u2a dim1 ix1 w8+ , testProperty "Word16" $ test_u2a dim1 ix1 w16+ , testProperty "Word32" $ test_u2a dim1 ix1 w32+ , testProperty "Word64" $ test_u2a dim1 ix1 w64+ , testProperty "Float" $ test_u2a dim1 ix1 f32+ , testProperty "Double" $ test_u2a dim1 ix1 f64+ ]+ , testGroup "DIM2"+ [ testProperty "Int" $ test_u2a dim2 ix2 int+ , testProperty "Int8" $ test_u2a dim2 ix2 i8+ , testProperty "Int16" $ test_u2a dim2 ix2 i16+ , testProperty "Int32" $ test_u2a dim2 ix2 i32+ , testProperty "Int64" $ test_u2a dim2 ix2 i64+ , testProperty "Word" $ test_u2a dim2 ix2 word+ , testProperty "Word8" $ test_u2a dim2 ix2 w8+ , testProperty "Word16" $ test_u2a dim2 ix2 w16+ , testProperty "Word32" $ test_u2a dim2 ix2 w32+ , testProperty "Word64" $ test_u2a dim2 ix2 w64+ , testProperty "Float" $ test_u2a dim2 ix2 f32+ , testProperty "Double" $ test_u2a dim2 ix2 f64+ ]+ ]+ , testGroup "accelerate->uarray"+ [ testGroup "DIM1"+ [ testProperty "Int" $ test_a2u dim1 ix1 int+ , testProperty "Int8" $ test_a2u dim1 ix1 i8+ , testProperty "Int16" $ test_a2u dim1 ix1 i16+ , testProperty "Int32" $ test_a2u dim1 ix1 i32+ , testProperty "Int64" $ test_a2u dim1 ix1 i64+ , testProperty "Word" $ test_a2u dim1 ix1 word+ , testProperty "Word8" $ test_a2u dim1 ix1 w8+ , testProperty "Word16" $ test_a2u dim1 ix1 w16+ , testProperty "Word32" $ test_a2u dim1 ix1 w32+ , testProperty "Word64" $ test_a2u dim1 ix1 w64+ , testProperty "Float" $ test_a2u dim1 ix1 f32+ , testProperty "Double" $ test_a2u dim1 ix1 f64+ ]+ , testGroup "DIM2"+ [ testProperty "Int" $ test_a2u dim2 ix2 int+ , testProperty "Int8" $ test_a2u dim2 ix2 i8+ , testProperty "Int16" $ test_a2u dim2 ix2 i16+ , testProperty "Int32" $ test_a2u dim2 ix2 i32+ , testProperty "Int64" $ test_a2u dim2 ix2 i64+ , testProperty "Word" $ test_a2u dim2 ix2 word+ , testProperty "Word8" $ test_a2u dim2 ix2 w8+ , testProperty "Word16" $ test_a2u dim2 ix2 w16+ , testProperty "Word32" $ test_a2u dim2 ix2 w32+ , testProperty "Word64" $ test_a2u dim2 ix2 w64+ , testProperty "Float" $ test_a2u dim2 ix2 f32+ , testProperty "Double" $ test_a2u dim2 ix2 f64+ ]+ ]+ ]+
+ test/Test/Util.hs view
@@ -0,0 +1,122 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE ViewPatterns #-}+-- |+-- Module : Test.Util+-- Copyright : [2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--++module Test.Util where++import Data.Array.Accelerate ( Arrays, Array, Acc, Shape, Elt )+import Data.Array.Accelerate.Trafo ( Afunction, AfunctionR )+import Data.Array.Accelerate.Array.Sugar ( DIM1, DIM2, Z(..), (:.)(..), fromList, size )+import Data.Array.Accelerate.Data.Complex++import Hedgehog+import qualified Hedgehog.Gen as Gen+import qualified Hedgehog.Range as Range++import Data.Int+import Data.Word+import Prelude as P+++type Run = forall a. Arrays a => Acc a -> a+type RunN = forall f. Afunction f => f -> AfunctionR f++floating :: P.RealFloat a => Gen a+floating = Gen.realFloat (Range.linearFracFrom 0 (-1) 1)++complex :: Gen a -> Gen (Complex a)+complex f = (:+) <$> f <*> f++dim0 :: Gen Z+dim0 = return Z++dim1 :: Gen DIM1+dim1 = (Z :.) <$> Gen.int (Range.linear 0 1024)++dim2 :: Gen DIM2+dim2 = do+ x <- Gen.int (Range.linear 0 128)+ y <- Gen.int (Range.linear 0 128)+ return (Z :. y :. x)++ix1 :: Gen (Int,Int)+ix1 = do+ lo <- Gen.int (Range.linearFrom 0 (-128) 128)+ hi <- Gen.int (Range.linear lo (lo+256))+ return (lo,hi)++ix2 :: Gen ((Int,Int), (Int,Int))+ix2 = do+ l0 <- Gen.int (Range.linearFrom 0 (-64) (64))+ l1 <- Gen.int (Range.linearFrom 0 (-64) (64))+ h0 <- Gen.int (Range.linear l0 (l0+128))+ h1 <- Gen.int (Range.linear l1 (l1+128))+ return ((l0,l1), (h0,h1))++array :: (Shape sh, Elt e) => sh -> Gen e -> Gen (Array sh e)+array sh gen = fromList sh <$> Gen.list (Range.singleton (size sh)) gen++int :: Gen Int+int = Gen.int Range.linearBounded++i8 :: Gen Int8+i8 = Gen.int8 Range.linearBounded++i16 :: Gen Int16+i16 = Gen.int16 Range.linearBounded++i32 :: Gen Int32+i32 = Gen.int32 Range.linearBounded++i64 :: Gen Int64+i64 = Gen.int64 Range.linearBounded++word :: Gen Word+word = Gen.word Range.linearBounded++w8 :: Gen Word8+w8 = Gen.word8 Range.linearBounded++w16 :: Gen Word16+w16 = Gen.word16 Range.linearBounded++w32 :: Gen Word32+w32 = Gen.word32 Range.linearBounded++w64 :: Gen Word64+w64 = Gen.word64 Range.linearBounded++f32 :: Gen Float+f32 = Gen.float (Range.linearFracFrom 0 flt_min flt_max)++f64 :: Gen Double+f64 = Gen.double (Range.linearFracFrom 0 flt_min flt_max)++flt_max :: RealFloat a => a+flt_max = x+ where+ n = floatDigits x+ b = floatRadix x+ (_, u) = floatRange x+ x = encodeFloat (b^n - 1) (u - n)++flt_min :: RealFloat a => a+flt_min = x+ where+ n = floatDigits x+ b = floatRadix x+ (l, _) = floatRange x+ x = encodeFloat (b^n - 1) (l - n - 1)+
+ test/Test/Vector/Storable.hs view
@@ -0,0 +1,184 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+-- |+-- Module : Test.Vector.Storable+-- Copyright : [2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--++module Test.Vector.Storable+ where++import Test.Util+import Test.Tasty+import Test.Tasty.Hedgehog++import Data.Array.Accelerate ( Shape, Elt, Z(..), (:.)(..) )+import Data.Array.Accelerate.Array.Sugar ( rank, EltRepr )+import Data.Array.Accelerate.Data.Complex+import Data.Array.Accelerate.IO.Data.Vector.Storable as A+import qualified Data.Array.Accelerate as A++import Data.Vector.Storable as S++import Hedgehog+import qualified Hedgehog.Gen as Gen+import qualified Hedgehog.Range as Range++import Data.Word+import Text.Printf+import Prelude as P+++storable :: Storable e => Int -> Gen e -> Gen (S.Vector e)+storable n gen =+ S.fromListN n <$> Gen.list (Range.singleton n) gen++boolToWord8 :: Bool -> Word8+boolToWord8 True = 1+boolToWord8 False = 0++test_s2a+ :: forall e. (Storable e, Elt e, Eq e, Vectors (EltRepr e) ~ Vector e)+ => Gen e+ -> Property+test_s2a e =+ property $ do+ sh@(Z :. n) <- forAll dim1+ svec <- forAll (storable n e)+ --+ S.toList svec === A.toList (A.fromVectors sh svec)++test_s2a_t2+ :: forall a b. ( Storable a, Elt a, Eq a, Vectors (EltRepr a) ~ Vector a+ , Storable b, Elt b, Eq b, Vectors (EltRepr b) ~ Vector b+ )+ => Gen a+ -> Gen b+ -> Property+test_s2a_t2 a b =+ property $ do+ sh@(Z :. n) <- forAll dim1+ sa <- forAll (storable n a)+ sb <- forAll (storable n b)+ --+ P.zip (S.toList sa) (S.toList sb) === A.toList (A.fromVectors sh (((), sa), sb))+++test_a2s+ :: forall sh e. (Shape sh, Storable e, Elt e, Eq sh, Eq e, Vectors (EltRepr e) ~ Vector e)+ => Gen sh+ -> Gen e+ -> Property+test_a2s dim e =+ property $ do+ sh <- forAll dim+ arr <- forAll (array sh e)+ --+ A.toList arr === S.toList (A.toVectors arr)++test_a2s_t2+ :: forall sh a b. ( Shape sh, Eq sh, Eq a, Eq b, Elt a, Elt b, Storable a, Storable b+ , Vectors (EltRepr (a,b)) ~ (((), Vector a), Vector b)+ )+ => Gen sh+ -> Gen (a,b)+ -> Property+test_a2s_t2 dim e =+ property $ do+ sh <- forAll dim+ arr <- forAll (array sh e)+ let+ (((), va), vb) = A.toVectors arr+ --+ A.toList arr === P.zip (S.toList va) (S.toList vb)+++test_s2a_complex+ :: forall e. ( Storable e, Elt (Complex e), Eq e+ , Vectors (EltRepr (Complex e)) ~ Vector e+ )+ => Gen (Complex e)+ -> Property+test_s2a_complex e =+ property $ do+ sh@(Z :. n) <- forAll dim1+ svec <- forAll (storable n e)+ --+ S.toList svec === A.toList (A.fromVectors sh (S.unsafeCast svec :: S.Vector e))++test_a2s_complex+ :: forall sh e. ( Shape sh, Storable e, Elt (Complex e), Eq sh, Eq e+ , Vectors (EltRepr (Complex e)) ~ Vector e+ )+ => Gen sh+ -> Gen (Complex e)+ -> Property+test_a2s_complex dim e =+ property $ do+ sh <- forAll dim+ arr <- forAll (array sh e)+ --+ A.toList arr === S.toList (S.unsafeCast (A.toVectors arr) :: S.Vector (Complex e))+++test_a2s_dim+ :: forall sh. (Shape sh, Eq sh)+ => Gen sh+ -> TestTree+test_a2s_dim dim =+ testGroup (printf "DIM%d" (rank (undefined::sh)))+ [ testProperty "Int" $ test_a2s dim int+ , testProperty "Int8" $ test_a2s dim i8+ , testProperty "Int16" $ test_a2s dim i16+ , testProperty "Int32" $ test_a2s dim i32+ , testProperty "Int64" $ test_a2s dim i64+ , testProperty "Word" $ test_a2s dim word+ , testProperty "Word8" $ test_a2s dim w8+ , testProperty "Word16" $ test_a2s dim w16+ , testProperty "Word32" $ test_a2s dim w32+ , testProperty "Word64" $ test_a2s dim w64+ , testProperty "Char" $ test_a2s dim Gen.unicode+ -- , testProperty "Bool" $ test_a2s dim Gen.bool+ , testProperty "Float" $ test_a2s dim f32+ , testProperty "Double" $ test_a2s dim f64+ , testProperty "Complex Float" $ test_a2s_complex dim (complex f32)+ , testProperty "(Double, Int16)" $ test_a2s_t2 dim ((,) <$> f64 <*> i16)+ , testProperty "(Float, Float)" $ test_a2s_t2 dim ((,) <$> f32 <*> f32)+ -- , testProperty "(Float, (Double,Int))" $ test_a2s dim ((,) <$> f32 <*> ((,) <$> f64 <*> int))+ ]++test_vector_storable :: TestTree+test_vector_storable =+ testGroup "Data.Vector.Storable"+ [ testGroup "storable->accelerate"+ [ testProperty "Int" $ test_s2a int+ , testProperty "Int8" $ test_s2a i8+ , testProperty "Int16" $ test_s2a i16+ , testProperty "Int32" $ test_s2a i32+ , testProperty "Int64" $ test_s2a i64+ , testProperty "Word" $ test_s2a word+ , testProperty "Word8" $ test_s2a w8+ , testProperty "Word16" $ test_s2a w16+ , testProperty "Word32" $ test_s2a w32+ , testProperty "Word64" $ test_s2a w64+ , testProperty "Char" $ test_s2a Gen.unicode+ , testProperty "Bool" $ test_s2a (boolToWord8 <$> Gen.bool)+ , testProperty "Float" $ test_s2a f32+ , testProperty "Double" $ test_s2a f64+ , testProperty "Complex Float" $ test_s2a_complex (complex f32)+ , testProperty "(Int,Float)" $ test_s2a_t2 int f32+ , testProperty "(Int8,Word)" $ test_s2a_t2 i8 word+ ]+ , testGroup"accelerate->storable"+ [ test_a2s_dim dim0+ , test_a2s_dim dim1+ , test_a2s_dim dim2+ ]+ ]+
+ test/Test/Vector/Unboxed.hs view
@@ -0,0 +1,113 @@+{-# LANGUAGE ScopedTypeVariables #-}+-- |+-- Module : Test.Vector.Unboxed+-- Copyright : [2017] Trevor L. McDonell+-- License : BSD3+--+-- Maintainer : Trevor L. McDonell <tmcdonell@cse.unsw.edu.au>+-- Stability : experimental+-- Portability : non-portable (GHC extensions)+--++module Test.Vector.Unboxed+ where++import Test.Util+import Test.Tasty+import Test.Tasty.Hedgehog++import Data.Array.Accelerate ( Shape, Elt, Z(..), (:.)(..) )+import Data.Array.Accelerate.Array.Sugar ( rank )+import Data.Array.Accelerate.IO.Data.Vector.Unboxed as A+import qualified Data.Array.Accelerate as A++import Data.Vector.Unboxed as U++import Hedgehog+import qualified Hedgehog.Gen as Gen+import qualified Hedgehog.Range as Range++import Text.Printf+++unboxed :: U.Unbox e => Int -> Gen e -> Gen (U.Vector e)+unboxed n gen =+ U.fromListN n <$> Gen.list (Range.singleton n) gen++test_u2a+ :: (A.Unbox e, Show e, Eq e)+ => Gen e+ -> Property+test_u2a e =+ property $ do+ Z :. n <- forAll dim1+ uvec <- forAll (unboxed n e)+ --+ U.toList uvec === A.toList (A.fromUnboxed uvec)++test_a2u+ :: forall sh e. (A.Unbox e, Shape sh, Elt e, Eq sh, Eq e)+ => Gen sh+ -> Gen e+ -> Property+test_a2u dim e =+ property $ do+ sh <- forAll dim+ arr <- forAll (array sh e)+ --+ A.toList arr === U.toList (A.toUnboxed arr)++test_a2u_dim+ :: forall sh. (Shape sh, Eq sh)+ => Gen sh+ -> TestTree+test_a2u_dim dim =+ testGroup (printf "DIM%d" (rank (undefined::sh)))+ [ testProperty "Int" $ test_a2u dim int+ , testProperty "Int8" $ test_a2u dim i8+ , testProperty "Int16" $ test_a2u dim i16+ , testProperty "Int32" $ test_a2u dim i32+ , testProperty "Int64" $ test_a2u dim i64+ , testProperty "Word" $ test_a2u dim word+ , testProperty "Word8" $ test_a2u dim w8+ , testProperty "Word16" $ test_a2u dim w16+ , testProperty "Word32" $ test_a2u dim w32+ , testProperty "Word64" $ test_a2u dim w64+ , testProperty "Char" $ test_a2u dim Gen.unicode+ , testProperty "Bool" $ test_a2u dim Gen.bool+ , testProperty "Float" $ test_a2u dim f32+ , testProperty "Double" $ test_a2u dim f64+ -- , testProperty "Complex Float" $ test_a2u dim (complex f32)+ , testProperty "(Double, Int16)" $ test_a2u dim ((,) <$> f64 <*> i16)+ , testProperty "(Float, (Double,Int))" $ test_a2u dim ((,) <$> f32 <*> ((,) <$> f64 <*> int))+ ]++test_vector_unboxed :: TestTree+test_vector_unboxed =+ testGroup "Data.Vector.Unboxed"+ [ testGroup "unboxed->accelerate"+ [ testProperty "Int" $ test_u2a int+ , testProperty "Int8" $ test_u2a i8+ , testProperty "Int16" $ test_u2a i16+ , testProperty "Int32" $ test_u2a i32+ , testProperty "Int64" $ test_u2a i64+ , testProperty "Word" $ test_u2a word+ , testProperty "Word8" $ test_u2a w8+ , testProperty "Word16" $ test_u2a w16+ , testProperty "Word32" $ test_u2a w32+ , testProperty "Word64" $ test_u2a w64+ , testProperty "Char" $ test_u2a Gen.unicode+ , testProperty "Bool" $ test_u2a Gen.bool+ , testProperty "Float" $ test_u2a f32+ , testProperty "Double" $ test_u2a f64+ -- , testProperty "Complex Float" $ test_u2a (complex f32)+ , testProperty "(Int,Float)" $ test_u2a ((,) <$> int <*> f32)+ , testProperty "((Int8,Word),Double)" $ test_u2a ((,) <$> ((,) <$> i8 <*> word) <*> f64)+ ]+ , testGroup"accelerate->unboxed"+ [ test_a2u_dim dim0+ , test_a2u_dim dim1+ , test_a2u_dim dim2+ ]+ ]+