accelerate-fftw 1.0.2 → 1.0.3
raw patch · 6 files changed
+196/−38 lines, 6 filesdep +accelerate-fftwdep +accelerate-utilitydep +doctest-exitcode-stdioPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: accelerate-fftw, accelerate-utility, doctest-exitcode-stdio, doctest-lib
API changes (from Hackage documentation)
- Data.Array.Accelerate.FFTW.Manifest: type Element a = (FFTWReal a, Elt (Complex a), ForeignPtrs (EltR (Complex a)) ~ ForeignPtr (Complex a))
+ Data.Array.Accelerate.FFTW.Manifest: type Element a = (FFTWReal a, ComplexElement a (Complex a))
Files
- Justfile +9/−0
- accelerate-fftw.cabal +24/−5
- src/Data/Array/Accelerate/CArray/Conversion.hs +32/−25
- src/Data/Array/Accelerate/FFTW/Manifest.hs +56/−8
- test/Test.hs +10/−0
- test/Test/Data/Array/Accelerate/FFTW/Manifest.hs +65/−0
+ Justfile view
@@ -0,0 +1,9 @@+run-test: update-test+ runhaskell Setup.lhs configure --user --enable-tests+ runhaskell Setup.lhs build+ ./dist/build/accelerate-fftw-test/accelerate-fftw-test++update-test:+ doctest-extract-0.1 -i src/ -o test/ \+ --import-tested --module-prefix Test --executable-main=Test.hs \+ Data.Array.Accelerate.FFTW.Manifest
accelerate-fftw.cabal view
@@ -1,6 +1,7 @@+Cabal-Version: 2.2 Name: accelerate-fftw-Version: 1.0.2-License: BSD3+Version: 1.0.3+License: BSD-3-Clause License-File: LICENSE Author: Henning Thielemann <haskell@henning-thielemann.de> Maintainer: Henning Thielemann <haskell@henning-thielemann.de>@@ -10,12 +11,13 @@ Description: An interface to the Fastest Fourier Transform in the West (FFTW) for the @accelerate@ framework.-Tested-With: GHC==7.8.3-Cabal-Version: 1.14+Tested-With: GHC==9.2.8 Build-Type: Simple+Extra-Source-Files:+ Justfile Source-Repository this- Tag: 1.0.2+ Tag: 1.0.3 Type: darcs Location: https://hub.darcs.net/thielema/accelerate-fftw/ @@ -39,3 +41,20 @@ Data.Array.Accelerate.FFTW.Manifest Other-Modules: Data.Array.Accelerate.CArray.Conversion++Test-Suite accelerate-fftw-test+ Type: exitcode-stdio-1.0+ Build-Depends:+ doctest-exitcode-stdio >=0.0 && <0.1,+ doctest-lib >=0.1.1 && <0.2,+ accelerate-fftw,+ accelerate-utility >=1.1 && <1.2,+ accelerate >=1.3 && <1.5,+ base >=4.5 && <5++ GHC-Options: -Wall+ Hs-Source-Dirs: test+ Default-Language: Haskell98+ Main-Is: Test.hs+ Other-Modules:+ Test.Data.Array.Accelerate.FFTW.Manifest
src/Data/Array/Accelerate/CArray/Conversion.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-}+{-# LANGUAGE ConstraintKinds #-} module Data.Array.Accelerate.CArray.Conversion where import qualified Data.Array.Accelerate.IO.Foreign.ForeignPtr as AIO@@ -15,19 +16,26 @@ import Data.Array.Accelerate.Data.Complex (Complex) import System.IO.Unsafe (unsafePerformIO)-import Foreign.ForeignPtr (ForeignPtr,)+import Foreign.ForeignPtr (ForeignPtr, castForeignPtr) import Foreign.Storable (Storable) +type RealElement a =+ (A.Elt a, Storable a, AIO.ForeignPtrs (EltR a) ~ ForeignPtr a)++type ComplexElement a ac =+ (Storable a, RealFloat a, Complex a ~ ac, A.Elt ac,+ AIO.ForeignPtrs (EltR ac) ~ ForeignPtr a)+ accFromCArrayReal1D ::- (A.Elt a, Storable a, AIO.ForeignPtrs (EltR a) ~ ForeignPtr a) =>+ (RealElement a) => CArray Int a -> Array DIM1 a accFromCArrayReal1D arr = let (len, fptr) = CArray.toForeignPtr arr in AIO.fromForeignPtrs (Z :. len) fptr accFromCArrayReal2D ::- (A.Elt a, Storable a, AIO.ForeignPtrs (EltR a) ~ ForeignPtr a) =>+ (RealElement a) => CArray (Int, Int) a -> Array DIM2 a accFromCArrayReal2D arr = AIO.fromForeignPtrs@@ -36,28 +44,29 @@ accFromCArrayComplex1D ::- (Storable a, RealFloat a, Complex a ~ ac, A.Elt ac,- AIO.ForeignPtrs (EltR ac) ~ ForeignPtr ac) =>+ (ComplexElement a ac) => CArray Int (Complex a) -> Array DIM1 (Complex a) accFromCArrayComplex1D arr = accFromCArrayComplex (accDimsFromArrayBounds1D $ CArray.bounds arr) arr accFromCArrayComplex2D ::- (Storable a, RealFloat a, Complex a ~ ac, A.Elt ac,- AIO.ForeignPtrs (EltR ac) ~ ForeignPtr ac) =>+ (ComplexElement a ac) => CArray (Int, Int) (Complex a) -> Array DIM2 (Complex a) accFromCArrayComplex2D arr = accFromCArrayComplex (accDimsFromArrayBounds2D $ CArray.bounds arr) arr accFromCArrayComplex ::- (Ix i, A.Shape sh, Storable a, RealFloat a, Complex a ~ ac, A.Elt ac,- AIO.ForeignPtrs (EltR ac) ~ ForeignPtr ac) =>+ (Ix i, A.Shape sh, ComplexElement a ac) => sh -> CArray i ac -> Array sh ac accFromCArrayComplex sh arr =- AIO.fromForeignPtrs sh (snd $ CArray.toForeignPtr arr)+ AIO.fromForeignPtrs sh $+ castForeignPtrFromComplex $ snd $ CArray.toForeignPtr arr +castForeignPtrFromComplex :: ForeignPtr (Complex a) -> ForeignPtr a+castForeignPtrFromComplex = castForeignPtr + accDimsFromArrayBounds1D :: (CArray.Ix i) => (i, i) -> DIM1 accDimsFromArrayBounds1D bnds = Z :. rangeSize bnds @@ -68,7 +77,7 @@ cArrayFromAccReal1D ::- (A.Elt a, Storable a, AIO.ForeignPtrs (EltR a) ~ ForeignPtr a) =>+ (RealElement a) => Array DIM1 a -> CArray Int a cArrayFromAccReal1D arr = let (Z:.len) = A.arrayShape arr@@ -76,7 +85,7 @@ unsafeForeignPtrToCArray (AIO.toForeignPtrs arr) (0,len-1) cArrayFromAccReal2D ::- (A.Elt a, Storable a, AIO.ForeignPtrs (EltR a) ~ ForeignPtr a) =>+ (RealElement a) => Array DIM2 a -> CArray (Int, Int) a cArrayFromAccReal2D arr = unsafePerformIO $@@ -84,38 +93,36 @@ (arrayBounds2DFromAccDims $ A.arrayShape arr) cArrayFromAccComplex1D ::- (Storable a, RealFloat a, Complex a ~ ac, A.Elt ac,- AIO.ForeignPtrs (EltR ac) ~ ForeignPtr ac) =>+ (ComplexElement a ac) => Array DIM1 ac -> CArray Int ac cArrayFromAccComplex1D arr = cArrayFromAccComplex (arrayBounds1DFromAccDims $ A.arrayShape arr) arr cArrayFromAccComplex2D ::- (Storable a, RealFloat a, Complex a ~ ac, A.Elt ac,- AIO.ForeignPtrs (EltR ac) ~ ForeignPtr ac) =>+ (ComplexElement a ac) => Array DIM2 ac -> CArray (Int,Int) ac cArrayFromAccComplex2D arr = cArrayFromAccComplex (arrayBounds2DFromAccDims $ A.arrayShape arr) arr cArrayFromAccComplex ::- (Ix i, A.Shape sh,- Storable a, RealFloat a, Complex a ~ ac, A.Elt ac,- AIO.ForeignPtrs (EltR ac) ~ ForeignPtr ac) =>+ (Ix i, A.Shape sh, ComplexElement a ac) => (i,i) -> Array sh ac -> CArray i ac cArrayFromAccComplex bnds arr = unsafePerformIO $- unsafeForeignPtrToCArray (AIO.toForeignPtrs arr) bnds+ unsafeForeignPtrToCArray+ (castForeignPtrToComplex $ AIO.toForeignPtrs arr) bnds +castForeignPtrToComplex :: ForeignPtr a -> ForeignPtr (Complex a)+castForeignPtrToComplex = castForeignPtr + withCArrayComplex ::- (Ix i, A.Shape sh,- Storable a, RealFloat a, Complex a ~ ac, A.Elt ac,- AIO.ForeignPtrs (EltR ac) ~ ForeignPtr ac) =>+ (Ix i, A.Shape sh, ComplexElement a ac) => (sh -> (i,i)) ->- (CArray i (Complex a) -> CArray i (Complex a)) ->- Array sh (Complex a) -> Array sh (Complex a)+ (CArray i ac -> CArray i ac) ->+ Array sh ac -> Array sh ac withCArrayComplex bndsFromSh f arr = let sh = A.arrayShape arr in accFromCArrayComplex sh $ f $
src/Data/Array/Accelerate/FFTW/Manifest.hs view
@@ -16,47 +16,95 @@ import qualified Data.Array.Accelerate.CArray.Conversion as Conv -import qualified Data.Array.Accelerate.IO.Foreign.ForeignPtr as AIO-import qualified Data.Array.Accelerate as A import qualified Data.Array.Accelerate.Sugar.Shape as Shape-import Data.Array.Accelerate.Sugar.Elt (EltR)+import qualified Data.Array.Accelerate as A import Data.Array.Accelerate (Array, (:.)((:.))) import Foreign.Storable.Complex () import Data.Array.Accelerate.Data.Complex (Complex) -import Foreign.ForeignPtr (ForeignPtr) +{- $setup+>>> import qualified Data.Array.Accelerate.Utility.Lift.Exp as Exp+>>> import qualified Data.Array.Accelerate.Interpreter as AI+>>> import qualified Data.Array.Accelerate as A+>>> import Data.Array.Accelerate.Utility.Lift.Exp (expr)+>>> import Data.Array.Accelerate.Data.Complex (Complex((:+)))+>>> import Data.Array.Accelerate ((:.)((:.)))+>>>+>>> roundComplex :: A.Exp (Complex Float) -> A.Exp (Complex Int)+>>> roundComplex =+>>> Exp.modify (expr:+expr) $ \(r:+i) -> A.round r :+ (A.round i :: A.Exp Int)+-} + type Bounds i = (i,i) type Transform sh a = Array sh a -> Array sh a -type Element a =- (FFTWReal a, A.Elt (Complex a),- AIO.ForeignPtrs (EltR (Complex a)) ~ ForeignPtr (Complex a))+type Element a = (FFTWReal a, Conv.ComplexElement a (Complex a)) +{- |+>>> AI.run1 (A.map roundComplex) $ dft (A.fromList (A.Z:.3:.3) [1000,0,0, 0,1000,0, 0,0,1000])+Matrix (Z :. 3 :. 3)+ [ 1000 :+ 0, 1000 :+ 0, 1000 :+ 0,+ 1000 :+ 0, (-500) :+ (-866), (-500) :+ 866,+ 1000 :+ 0, (-500) :+ 866, (-500) :+ (-866)]+-} dft :: (A.Shape sh, Element a) => Transform (sh:.Int) (Complex a) dft = Conv.withCArrayComplex bnds1 $ FFT.dftN [1] +{- |+>>> AI.run1 (A.map roundComplex) $ idft $ dft (A.fromList (A.Z:.3:.3) [1000,0,0, 0,1000,0, 0,0,1000])+Matrix (Z :. 3 :. 3)+ [ 1000 :+ 0, 0 :+ 0, 0 :+ 0,+ 0 :+ 0, 1000 :+ 0, 0 :+ 0,+ 0 :+ 0, 0 :+ 0, 1000 :+ 0]+-} idft :: (A.Shape sh, Element a) => Transform (sh:.Int) (Complex a)-idft = Conv.withCArrayComplex bnds1 $ FFT.dftN [1]+idft = Conv.withCArrayComplex bnds1 $ FFT.idftN [1] bnds1 :: (A.Shape sh) => sh:.Int -> Bounds (Int,Int) bnds1 (sh:.n) = ((0,0), (Shape.size sh-1, n-1)) +{- |+>>> AI.run1 (A.map roundComplex) $ dft2d (A.fromList (A.Z:.3:.3) [1000,0,0, 0,0,0, 0,0,0])+Matrix (Z :. 3 :. 3)+ [ 1000 :+ 0, 1000 :+ 0, 1000 :+ 0,+ 1000 :+ 0, 1000 :+ 0, 1000 :+ 0,+ 1000 :+ 0, 1000 :+ 0, 1000 :+ 0]++>>> AI.run1 (A.map roundComplex) $ dft2d (A.fromList (A.Z:.3:.3) [0,1000,0, 0,0,0, 0,0,0])+Matrix (Z :. 3 :. 3)+ [ 1000 :+ 0, (-500) :+ (-866), (-500) :+ 866,+ 1000 :+ 0, (-500) :+ (-866), (-500) :+ 866,+ 1000 :+ 0, (-500) :+ (-866), (-500) :+ 866]++>>> AI.run1 (A.map roundComplex) $ dft2d (A.fromList (A.Z:.3:.3) [1000,0,0, 0,1000,0, 0,0,1000])+Matrix (Z :. 3 :. 3)+ [ 3000 :+ 0, 0 :+ 0, 0 :+ 0,+ 0 :+ 0, 0 :+ 0, 3000 :+ 0,+ 0 :+ 0, 3000 :+ 0, 0 :+ 0]+-} dft2d :: (A.Shape sh, Element a) => Transform (sh:.Int:.Int) (Complex a) dft2d = Conv.withCArrayComplex bnds2 $ FFT.dftN [1,2] +{- |+>>> AI.run1 (A.map roundComplex) $ idft2d $ dft2d (A.fromList (A.Z:.3:.3) [1000,0,0, 0,1000,0, 0,0,1000])+Matrix (Z :. 3 :. 3)+ [ 1000 :+ 0, 0 :+ 0, 0 :+ 0,+ 0 :+ 0, 1000 :+ 0, 0 :+ 0,+ 0 :+ 0, 0 :+ 0, 1000 :+ 0]+-} idft2d :: (A.Shape sh, Element a) => Transform (sh:.Int:.Int) (Complex a)
+ test/Test.hs view
@@ -0,0 +1,10 @@+-- Do not edit! Automatically created with doctest-extract.+module Main where++import qualified Test.Data.Array.Accelerate.FFTW.Manifest++import qualified Test.DocTest.Driver as DocTest++main :: IO ()+main = DocTest.run $ do+ Test.Data.Array.Accelerate.FFTW.Manifest.test
+ test/Test/Data/Array/Accelerate/FFTW/Manifest.hs view
@@ -0,0 +1,65 @@+-- Do not edit! Automatically created with doctest-extract from src/Data/Array/Accelerate/FFTW/Manifest.hs+{-# LINE 28 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}++module Test.Data.Array.Accelerate.FFTW.Manifest where++import Data.Array.Accelerate.FFTW.Manifest+import Test.DocTest.Base+import qualified Test.DocTest.Driver as DocTest++{-# LINE 29 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+import qualified Data.Array.Accelerate.Utility.Lift.Exp as Exp+import qualified Data.Array.Accelerate.Interpreter as AI+import qualified Data.Array.Accelerate as A+import Data.Array.Accelerate.Utility.Lift.Exp (expr)+import Data.Array.Accelerate.Data.Complex (Complex((:+)))+import Data.Array.Accelerate ((:.)((:.)))++roundComplex :: A.Exp (Complex Float) -> A.Exp (Complex Int)+roundComplex =+ Exp.modify (expr:+expr) $ \(r:+i) -> A.round r :+ (A.round i :: A.Exp Int)++test :: DocTest.T ()+test = do+ DocTest.printPrefix "Data.Array.Accelerate.FFTW.Manifest:49: "+{-# LINE 49 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ DocTest.example(+{-# LINE 49 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ AI.run1 (A.map roundComplex) $ dft (A.fromList (A.Z:.3:.3) [1000,0,0, 0,1000,0, 0,0,1000])+ )+ [ExpectedLine [LineChunk "Matrix (Z :. 3 :. 3)"],ExpectedLine [LineChunk " [ 1000 :+ 0, 1000 :+ 0, 1000 :+ 0,"],ExpectedLine [LineChunk " 1000 :+ 0, (-500) :+ (-866), (-500) :+ 866,"],ExpectedLine [LineChunk " 1000 :+ 0, (-500) :+ 866, (-500) :+ (-866)]"]]+ DocTest.printPrefix "Data.Array.Accelerate.FFTW.Manifest:61: "+{-# LINE 61 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ DocTest.example(+{-# LINE 61 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ AI.run1 (A.map roundComplex) $ idft $ dft (A.fromList (A.Z:.3:.3) [1000,0,0, 0,1000,0, 0,0,1000])+ )+ [ExpectedLine [LineChunk "Matrix (Z :. 3 :. 3)"],ExpectedLine [LineChunk " [ 1000 :+ 0, 0 :+ 0, 0 :+ 0,"],ExpectedLine [LineChunk " 0 :+ 0, 1000 :+ 0, 0 :+ 0,"],ExpectedLine [LineChunk " 0 :+ 0, 0 :+ 0, 1000 :+ 0]"]]+ DocTest.printPrefix "Data.Array.Accelerate.FFTW.Manifest:77: "+{-# LINE 77 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ DocTest.example(+{-# LINE 77 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ AI.run1 (A.map roundComplex) $ dft2d (A.fromList (A.Z:.3:.3) [1000,0,0, 0,0,0, 0,0,0])+ )+ [ExpectedLine [LineChunk "Matrix (Z :. 3 :. 3)"],ExpectedLine [LineChunk " [ 1000 :+ 0, 1000 :+ 0, 1000 :+ 0,"],ExpectedLine [LineChunk " 1000 :+ 0, 1000 :+ 0, 1000 :+ 0,"],ExpectedLine [LineChunk " 1000 :+ 0, 1000 :+ 0, 1000 :+ 0]"]]+ DocTest.printPrefix "Data.Array.Accelerate.FFTW.Manifest:83: "+{-# LINE 83 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ DocTest.example(+{-# LINE 83 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ AI.run1 (A.map roundComplex) $ dft2d (A.fromList (A.Z:.3:.3) [0,1000,0, 0,0,0, 0,0,0])+ )+ [ExpectedLine [LineChunk "Matrix (Z :. 3 :. 3)"],ExpectedLine [LineChunk " [ 1000 :+ 0, (-500) :+ (-866), (-500) :+ 866,"],ExpectedLine [LineChunk " 1000 :+ 0, (-500) :+ (-866), (-500) :+ 866,"],ExpectedLine [LineChunk " 1000 :+ 0, (-500) :+ (-866), (-500) :+ 866]"]]+ DocTest.printPrefix "Data.Array.Accelerate.FFTW.Manifest:89: "+{-# LINE 89 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ DocTest.example(+{-# LINE 89 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ AI.run1 (A.map roundComplex) $ dft2d (A.fromList (A.Z:.3:.3) [1000,0,0, 0,1000,0, 0,0,1000])+ )+ [ExpectedLine [LineChunk "Matrix (Z :. 3 :. 3)"],ExpectedLine [LineChunk " [ 3000 :+ 0, 0 :+ 0, 0 :+ 0,"],ExpectedLine [LineChunk " 0 :+ 0, 0 :+ 0, 3000 :+ 0,"],ExpectedLine [LineChunk " 0 :+ 0, 3000 :+ 0, 0 :+ 0]"]]+ DocTest.printPrefix "Data.Array.Accelerate.FFTW.Manifest:102: "+{-# LINE 102 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ DocTest.example(+{-# LINE 102 "src/Data/Array/Accelerate/FFTW/Manifest.hs" #-}+ AI.run1 (A.map roundComplex) $ idft2d $ dft2d (A.fromList (A.Z:.3:.3) [1000,0,0, 0,1000,0, 0,0,1000])+ )+ [ExpectedLine [LineChunk "Matrix (Z :. 3 :. 3)"],ExpectedLine [LineChunk " [ 1000 :+ 0, 0 :+ 0, 0 :+ 0,"],ExpectedLine [LineChunk " 0 :+ 0, 1000 :+ 0, 0 :+ 0,"],ExpectedLine [LineChunk " 0 :+ 0, 0 :+ 0, 1000 :+ 0]"]]